import { useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Chip from '@mui/material/Chip'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useForm } from 'react-hook-form'
import {
  createMyAddress,
  deleteMyAddress,
  fetchMyAddresses,
  setMyAddressDefault,
  updateMyAddress,
} from '@/entities/user/api/address-api'
import type { ShippingAddress } from '@/entities/user/model/types'
import { AddressFormDialog, type AddressFormValues } from '@/features/address-form'

const defaultAddressForm = (isDefault: boolean): AddressFormValues => ({
  label: '',
  recipientName: '',
  recipientPhone: '',
  addressLine: '',
  comment: '',
  lat: null,
  lng: null,
  isDefault,
})

export function AddressesPage() {
  const queryClient = useQueryClient()
  const [open, setOpen] = useState(false)
  const [editing, setEditing] = useState<ShippingAddress | null>(null)

  const addressesQuery = useQuery({
    queryKey: ['me', 'addresses'],
    queryFn: fetchMyAddresses,
  })

  const form = useForm<AddressFormValues>({
    defaultValues: defaultAddressForm(false),
    mode: 'onChange',
  })

  const createMut = useMutation({
    mutationFn: async () => {
      const v = form.getValues()
      if (v.lat === null || v.lng === null) throw new Error('Выберите точку на карте')
      await createMyAddress({
        label: v.label.trim() || null,
        recipientName: v.recipientName.trim(),
        recipientPhone: v.recipientPhone.trim(),
        addressLine: v.addressLine.trim(),
        comment: v.comment.trim() || null,
        lat: v.lat,
        lng: v.lng,
        isDefault: v.isDefault,
      })
    },
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['me', 'addresses'] })
      setOpen(false)
    },
  })

  const updateMut = useMutation({
    mutationFn: async () => {
      const v = form.getValues()
      if (v.lat === null || v.lng === null) throw new Error('Выберите точку на карте')
      await updateMyAddress(editing!.id, {
        label: v.label.trim() || null,
        recipientName: v.recipientName.trim(),
        recipientPhone: v.recipientPhone.trim(),
        addressLine: v.addressLine.trim(),
        comment: v.comment.trim() || null,
        lat: v.lat,
        lng: v.lng,
        isDefault: v.isDefault,
      })
    },
    onSuccess: () => {
      void queryClient.invalidateQueries({ queryKey: ['me', 'addresses'] })
      setOpen(false)
    },
  })

  const deleteMut = useMutation({
    mutationFn: (id: string) => deleteMyAddress(id),
    onSuccess: () => void queryClient.invalidateQueries({ queryKey: ['me', 'addresses'] }),
  })

  const defaultMut = useMutation({
    mutationFn: (id: string) => setMyAddressDefault(id),
    onSuccess: () => void queryClient.invalidateQueries({ queryKey: ['me', 'addresses'] }),
  })

  const error = createMut.error ?? updateMut.error ?? deleteMut.error ?? defaultMut.error

  const items = addressesQuery.data?.items ?? []

  const openCreate = () => {
    setEditing(null)
    form.reset(defaultAddressForm(items.length === 0))
    setOpen(true)
  }

  const openEdit = (a: ShippingAddress) => {
    setEditing(a)
    form.reset({
      label: a.label ?? '',
      recipientName: a.recipientName,
      recipientPhone: a.recipientPhone,
      addressLine: a.addressLine,
      comment: a.comment ?? '',
      lat: a.lat,
      lng: a.lng,
      isDefault: a.isDefault,
    })
    setOpen(true)
  }

  const handleSubmit = () => {
    if (editing) updateMut.mutate()
    else createMut.mutate()
  }

  return (
    <Box>
      <Typography variant="h4" gutterBottom>
        Адреса доставки
      </Typography>

      <Typography color="text.secondary" sx={{ mb: 2 }}>
        Можно добавить несколько адресов. Для каждого адреса задаются ФИО и телефон получателя отдельно.
      </Typography>

      <Stack direction="row" spacing={2} sx={{ mb: 2 }}>
        <Button variant="contained" onClick={openCreate}>
          Добавить адрес
        </Button>
      </Stack>

      {addressesQuery.isError && (
        <Alert severity="error" sx={{ mb: 2 }}>
          Не удалось загрузить адреса. Проверьте, что вы вошли в аккаунт и сервер запущен.
        </Alert>
      )}
      {error && (
        <Alert severity="error" sx={{ mb: 2 }}>
          {(error as Error).message}
        </Alert>
      )}

      <Stack spacing={2}>
        {items.map((a) => (
          <Box
            key={a.id}
            sx={{
              border: 1,
              borderColor: 'divider',
              borderRadius: 2,
              p: 2,
              bgcolor: 'background.paper',
            }}
          >
            <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1} sx={{ alignItems: { sm: 'center' } }}>
              <Typography sx={{ fontWeight: 700, flexGrow: 1 }}>{a.label?.trim() ? a.label : 'Адрес'}</Typography>
              {a.isDefault && <Chip label="По умолчанию" color="primary" size="small" />}
            </Stack>

            <Typography sx={{ mt: 1 }}>{a.addressLine}</Typography>
            <Typography color="text.secondary" variant="body2" sx={{ mt: 0.5 }}>
              Получатель: {a.recipientName} · {a.recipientPhone}
            </Typography>
            {a.comment && (
              <Typography color="text.secondary" variant="body2" sx={{ mt: 0.5 }}>
                Комментарий: {a.comment}
              </Typography>
            )}

            <Stack direction="row" spacing={1} sx={{ mt: 1.5, flexWrap: 'wrap' }}>
              {!a.isDefault && (
                <Button size="small" onClick={() => defaultMut.mutate(a.id)} disabled={defaultMut.isPending}>
                  Сделать основным
                </Button>
              )}
              <Button size="small" onClick={() => openEdit(a)}>
                Изменить
              </Button>
              <Button
                size="small"
                color="error"
                disabled={deleteMut.isPending}
                onClick={() => {
                  if (!confirm('Удалить адрес?')) return
                  deleteMut.mutate(a.id)
                }}
              >
                Удалить
              </Button>
            </Stack>
          </Box>
        ))}

        {addressesQuery.isSuccess && items.length === 0 && (
          <Alert severity="info">Адресов пока нет — добавьте первый адрес доставки.</Alert>
        )}
      </Stack>

      <AddressFormDialog
        open={open}
        onClose={() => setOpen(false)}
        editing={Boolean(editing)}
        form={form}
        onSubmit={handleSubmit}
        isPending={createMut.isPending || updateMut.isPending}
      />
    </Box>
  )
}
