import { Fragment, useMemo, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import FormControl from '@mui/material/FormControl'
import InputLabel from '@mui/material/InputLabel'
import MenuItem from '@mui/material/MenuItem'
import Select from '@mui/material/Select'
import Stack from '@mui/material/Stack'
import Table from '@mui/material/Table'
import TableBody from '@mui/material/TableBody'
import TableCell from '@mui/material/TableCell'
import TableHead from '@mui/material/TableHead'
import TableRow from '@mui/material/TableRow'
import TextField from '@mui/material/TextField'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import {
  fetchAdminOrder,
  fetchAdminOrders,
  patchAdminOrderDeliveryFee,
  postAdminOrderMessage,
  setAdminOrderStatus,
} from '@/entities/order/api/admin-order-api'
import { deliveryCarrierLabelRu } from '@/shared/constants/delivery-carrier'
import { ORDER_STATUSES, getAdminNextOrderStatuses } from '@/shared/constants/order'
import { formatPriceRub } from '@/shared/lib/format-price'
import { groupOrdersByStatus } from '@/shared/lib/group-orders-by-status'
import { invalidateQueryKeys } from '@/shared/lib/invalidate-query-keys'
import { parseOrderAddressSnapshot } from '@/shared/lib/order-address-snapshot'
import { orderStatusLabelRu } from '@/shared/lib/order-status-labels'
import { AdminDialog } from '@/shared/ui/AdminDialog/AdminDialog'
import { ChatMessageBubble } from '@/shared/ui/ChatMessageBubble'
import { OrderMessageBody } from '@/shared/ui/OrderMessageBody'
import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor'

function DeliveryFeeAdjustmentForm({ orderId, deliveryFeeCents }: { orderId: string; deliveryFeeCents: number }) {
  const qc = useQueryClient()
  const [rub, setRub] = useState(() => String(deliveryFeeCents / 100))
  const feeMut = useMutation({
    mutationFn: () => patchAdminOrderDeliveryFee(orderId, Math.round(Number.parseFloat(rub) * 100)),
    onSuccess: async () => {
      await invalidateQueryKeys(qc, [
        ['admin', 'orders'],
        ['admin', 'orders', 'detail'],
        ['admin', 'orders', 'summary'],
      ])
    },
  })

  return (
    <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-end' } }}>
      <TextField
        size="small"
        label="Доставка, ₽"
        type="number"
        value={rub}
        onChange={(e) => setRub(e.target.value)}
        slotProps={{ htmlInput: { min: 0, step: 1 } }}
        sx={{ width: { xs: '100%', sm: 200 } }}
      />
      <Button
        variant="contained"
        disabled={
          feeMut.isPending ||
          !rub.trim() ||
          !Number.isFinite(Number.parseFloat(rub)) ||
          Number.parseFloat(rub) < 0 ||
          !Number.isInteger(Number.parseFloat(rub))
        }
        onClick={() => feeMut.mutate()}
      >
        Утвердить доставку и открыть оплату
      </Button>
    </Stack>
  )
}

export function AdminOrdersPage() {
  const qc = useQueryClient()
  const [q, setQ] = useState('')
  const [status, setStatus] = useState('')
  const [deliveryType, setDeliveryType] = useState<'delivery' | 'pickup' | ''>('')
  const [dialogOpen, setDialogOpen] = useState(false)
  const [selectedId, setSelectedId] = useState<string | null>(null)
  const [msg, setMsg] = useState('')

  const ordersQuery = useQuery({
    queryKey: ['admin', 'orders', { q, status, deliveryType }],
    queryFn: () =>
      fetchAdminOrders({
        q: q.trim() || undefined,
        status: status || undefined,
        deliveryType: deliveryType || undefined,
      }),
  })

  const orderDetailQuery = useQuery({
    queryKey: ['admin', 'orders', 'detail', selectedId],
    queryFn: () => fetchAdminOrder(selectedId!),
    enabled: Boolean(selectedId),
  })

  const statusMut = useMutation({
    mutationFn: (next: string) => setAdminOrderStatus(selectedId!, next),
    onSuccess: async () => {
      await invalidateQueryKeys(qc, [
        ['admin', 'orders'],
        ['admin', 'orders', 'detail'],
        ['admin', 'orders', 'summary'],
      ])
    },
  })

  const msgMut = useMutation({
    mutationFn: () => postAdminOrderMessage(selectedId!, msg.trim()),
    onSuccess: async () => {
      setMsg('')
      await invalidateQueryKeys(qc, [['admin', 'orders', 'detail']])
    },
  })

  const open = (id: string) => {
    setSelectedId(id)
    setDialogOpen(true)
  }

  const items = useMemo(() => ordersQuery.data?.items ?? [], [ordersQuery.data?.items])
  const groupedItems = useMemo(
    () =>
      groupOrdersByStatus(items, ORDER_STATUSES).map((group) => ({
        statusCode: group.status,
        items: group.items,
      })),
    [items],
  )

  const detail = orderDetailQuery.data?.item
  const canSendMessage = msg.replace(/<[^>]*>/g, ' ').trim().length > 0

  const deliverySnapshot = useMemo(
    () => (detail?.deliveryType === 'delivery' ? parseOrderAddressSnapshot(detail.addressSnapshotJson) : null),
    [detail],
  )

  const nextStatuses = useMemo(() => {
    if (!detail) return []
    return getAdminNextOrderStatuses(detail.status, detail.deliveryType ?? 'delivery')
  }, [detail])

  return (
    <Box>
      <Typography variant="h4" sx={{ mb: 2 }}>
        Заказы
      </Typography>

      <Typography variant="body2" color="text.secondary" sx={{ mb: 2 }}>
        Управление заказами доступно пользователю с правами администратора.
      </Typography>
      <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ mb: 2 }}>
        <TextField size="small" label="Поиск (id/email)" value={q} onChange={(e) => setQ(e.target.value)} fullWidth />
        <FormControl size="small" sx={{ minWidth: 220 }}>
          <InputLabel id="status-label">Статус</InputLabel>
          <Select
            labelId="status-label"
            label="Статус"
            value={status}
            onChange={(e) => setStatus(String(e.target.value))}
          >
            <MenuItem value="">
              <em>Все</em>
            </MenuItem>
            {ORDER_STATUSES.map((s) => (
              <MenuItem key={s} value={s}>
                {orderStatusLabelRu(s)}
              </MenuItem>
            ))}
          </Select>
        </FormControl>
        <FormControl size="small" sx={{ minWidth: 220 }}>
          <InputLabel id="delivery-type-label">Способ получения</InputLabel>
          <Select
            labelId="delivery-type-label"
            label="Способ получения"
            value={deliveryType}
            onChange={(e) => {
              const v = String(e.target.value)
              if (v === '' || v === 'delivery' || v === 'pickup') setDeliveryType(v)
            }}
          >
            <MenuItem value="">
              <em>Все</em>
            </MenuItem>
            <MenuItem value="delivery">Доставка</MenuItem>
            <MenuItem value="pickup">Самовывоз</MenuItem>
          </Select>
        </FormControl>
      </Stack>

      {ordersQuery.isError && <Alert severity="error">Не удалось загрузить заказы.</Alert>}

      <Table size="small">
        <TableHead>
          <TableRow>
            <TableCell>ID</TableCell>
            <TableCell>Покупатель</TableCell>
            <TableCell>Создан</TableCell>
            <TableCell>Сумма</TableCell>
            <TableCell>Позиций</TableCell>
            <TableCell align="right">Действия</TableCell>
          </TableRow>
        </TableHead>
        <TableBody>
          {groupedItems.map((group) => (
            <Fragment key={`group:${group.statusCode}`}>
              <TableRow>
                <TableCell colSpan={6} sx={{ fontWeight: 700, bgcolor: 'action.hover' }}>
                  {orderStatusLabelRu(group.statusCode)} ({group.items.length})
                </TableCell>
              </TableRow>
              {group.items.map((o) => (
                <TableRow key={o.id} hover>
                  <TableCell>{o.id.slice(-8)}</TableCell>
                  <TableCell>{o.user.email}</TableCell>
                  <TableCell>{new Date(o.createdAt).toLocaleString('ru-RU')}</TableCell>
                  <TableCell>{formatPriceRub(o.totalCents)}</TableCell>
                  <TableCell>{o.itemsCount}</TableCell>
                  <TableCell align="right">
                    <Button size="small" onClick={() => open(o.id)}>
                      Открыть
                    </Button>
                  </TableCell>
                </TableRow>
              ))}
            </Fragment>
          ))}
          {ordersQuery.isSuccess && items.length === 0 && (
            <TableRow>
              <TableCell colSpan={6} sx={{ color: 'text.secondary' }}>
                Заказов пока нет.
              </TableCell>
            </TableRow>
          )}
        </TableBody>
      </Table>

      <AdminDialog
        open={dialogOpen}
        onClose={() => setDialogOpen(false)}
        title="Заказ"
        maxWidth="md"
        loading={!detail && orderDetailQuery.isLoading}
        error={orderDetailQuery.isError ? 'Не удалось загрузить заказ.' : null}
      >
        {detail && (
          <Stack spacing={2} sx={{ mt: 1 }}>
            <Typography sx={{ fontWeight: 700 }}>
              #{detail.id.slice(-8)} · {detail.user.email} · {orderStatusLabelRu(detail.status)} ·{' '}
              {formatPriceRub(detail.totalCents)}
            </Typography>
            <Typography variant="body2" color="text.secondary">
              Получение: {detail.deliveryType === 'pickup' ? 'самовывоз' : 'доставка'}
              {(detail.paymentMethod ?? 'online') === 'on_pickup' ? ' · оплата при получении' : ' · онлайн-оплата'}
              {detail.deliveryType === 'delivery' && deliveryCarrierLabelRu(detail.deliveryCarrier) && (
                <> · служба: {deliveryCarrierLabelRu(detail.deliveryCarrier)}</>
              )}
            </Typography>

            {detail.deliveryType === 'delivery' && (
              <Box
                sx={{
                  border: 1,
                  borderColor: 'divider',
                  borderRadius: 1,
                  p: 1.5,
                  bgcolor: 'action.hover',
                }}
              >
                <Typography variant="subtitle2" gutterBottom sx={{ fontWeight: 700 }}>
                  Адрес и получатель (на момент заказа)
                </Typography>
                {deliverySnapshot ? (
                  <Stack spacing={0.75}>
                    {deliverySnapshot.label?.trim() && (
                      <Typography variant="body2" color="text.secondary">
                        Метка: {deliverySnapshot.label}
                      </Typography>
                    )}
                    <Typography variant="body2">
                      <Box component="span" sx={{ color: 'text.secondary' }}>
                        Адрес:
                      </Box>{' '}
                      {deliverySnapshot.addressLine ?? '—'}
                    </Typography>
                    <Typography variant="body2">
                      <Box component="span" sx={{ color: 'text.secondary' }}>
                        Получатель:
                      </Box>{' '}
                      {deliverySnapshot.recipientName ?? '—'}
                    </Typography>
                    <Typography variant="body2">
                      <Box component="span" sx={{ color: 'text.secondary' }}>
                        Телефон:
                      </Box>{' '}
                      {deliverySnapshot.recipientPhone ?? '—'}
                    </Typography>
                    {deliverySnapshot.comment?.trim() && (
                      <Typography variant="body2" color="text.secondary">
                        Комментарий к адресу: {deliverySnapshot.comment}
                      </Typography>
                    )}
                  </Stack>
                ) : (
                  <Typography color="text.secondary" variant="body2">
                    Данные адреса в заказе отсутствуют или не распознаны.
                  </Typography>
                )}
              </Box>
            )}

            {detail.status === 'DELIVERY_FEE_ADJUSTMENT' && (
              <Alert severity="info">
                Укажите итоговую стоимость доставки (₽). После сохранения заказ получит статус «
                {orderStatusLabelRu('PENDING_PAYMENT')}», и клиент сможет оплатить с учётом этой суммы.
              </Alert>
            )}

            {detail.status === 'DELIVERY_FEE_ADJUSTMENT' && (
              <DeliveryFeeAdjustmentForm
                key={detail.id}
                orderId={detail.id}
                deliveryFeeCents={detail.deliveryFeeCents}
              />
            )}

            <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'center' } }}>
              <FormControl size="small" sx={{ minWidth: 240 }}>
                <InputLabel id="next-status-label">Сменить статус</InputLabel>
                <Select
                  labelId="next-status-label"
                  label="Сменить статус"
                  value=""
                  onChange={(e) => {
                    const next = String(e.target.value)
                    if (!next) return
                    statusMut.mutate(next)
                  }}
                  disabled={statusMut.isPending || nextStatuses.length === 0}
                >
                  <MenuItem value="">
                    <em>Выберите…</em>
                  </MenuItem>
                  {nextStatuses.map((s) => (
                    <MenuItem key={s} value={s}>
                      {orderStatusLabelRu(s)}
                    </MenuItem>
                  ))}
                </Select>
              </FormControl>
            </Stack>

            <Box>
              <Typography variant="subtitle2" sx={{ mb: 1 }}>
                Сообщения
              </Typography>
              <Stack spacing={1} sx={{ mb: 1 }}>
                {detail.messages.map((m) => (
                  <ChatMessageBubble key={m.id} authorType={m.authorType === 'admin' ? 'user' : 'admin'}>
                    <Typography variant="caption" color="text.secondary">
                      {m.authorType === 'admin' ? 'Админ (вы)' : 'Пользователь'} ·{' '}
                      {new Date(m.createdAt).toLocaleString()}
                    </Typography>
                    <OrderMessageBody text={m.text} attachmentUrl={m.attachmentUrl} />
                  </ChatMessageBubble>
                ))}
                {detail.messages.length === 0 && <Typography color="text.secondary">Нет сообщений.</Typography>}
              </Stack>

              <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ alignItems: { sm: 'flex-end' } }}>
                <Box sx={{ flexGrow: 1, width: '100%' }}>
                  <RichTextMessageEditor value={msg} onChange={setMsg} placeholder="Ответ админа" />
                </Box>
                <Button
                  variant="contained"
                  onClick={() => msgMut.mutate()}
                  disabled={msgMut.isPending || !canSendMessage}
                  sx={{ minWidth: 160 }}
                >
                  Отправить
                </Button>
              </Stack>
            </Box>
          </Stack>
        )}
      </AdminDialog>
    </Box>
  )
}
