import { useEffect, useMemo, useState } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Dialog from '@mui/material/Dialog'
import DialogActions from '@mui/material/DialogActions'
import DialogContent from '@mui/material/DialogContent'
import DialogTitle from '@mui/material/DialogTitle'
import Divider from '@mui/material/Divider'
import Rating from '@mui/material/Rating'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import axios from 'axios'
import { Link as RouterLink, useParams } from 'react-router-dom'
import {
  confirmOrderReceived,
  fetchMyOrder,
  fetchOrderReviewEligibility,
  payOrderStub,
  postOrderMessage,
} from '@/entities/order/api/order-api'
import { postProductReview, uploadReviewImage } from '@/entities/product/api/reviews-api'
import { markOrderMessagesRead } from '@/entities/user/api/messages-api'
import { formatPriceRub } from '@/shared/lib/format-price'
import { orderStatusLabelRu } from '@/shared/lib/order-status-labels'
import { RichTextMessageContent } from '@/shared/ui/RichTextMessageContent'
import { RichTextMessageEditor } from '@/shared/ui/RichTextMessageEditor'

function reviewSubmitErrorMessage(err: unknown): string {
  if (axios.isAxiosError(err)) {
    const status = err.response?.status
    const raw = err.response?.data
    const apiMsg =
      raw && typeof raw === 'object' && 'error' in raw && typeof (raw as { error: unknown }).error === 'string'
        ? (raw as { error: string }).error
        : null
    if (status === 409 || apiMsg?.toLowerCase().includes('уже')) {
      return 'Вы уже оставляли отзыв на этот товар.'
    }
    return apiMsg || err.message || 'Не удалось отправить отзыв'
  }
  if (err instanceof Error) return err.message
  return 'Не удалось отправить отзыв'
}

type AddressSnapshot = {
  deliveryType?: 'delivery' | 'pickup'
  label?: string | null
  recipientName?: string
  recipientPhone?: string
  addressLine?: string
  comment?: string | null
}

export function OrderDetailPage() {
  const { id } = useParams()
  const qc = useQueryClient()
  const [text, setText] = useState('')
  const [reviewTarget, setReviewTarget] = useState<{ productId: string; title: string } | null>(null)
  const [reviewRating, setReviewRating] = useState<number>(5)
  const [reviewText, setReviewText] = useState('')
  const [reviewImageUrl, setReviewImageUrl] = useState<string | null>(null)

  const orderQuery = useQuery({
    queryKey: ['me', 'orders', id],
    queryFn: () => fetchMyOrder(id!),
    enabled: Boolean(id),
  })

  const payMut = useMutation({
    mutationFn: () => payOrderStub(id!),
    onSuccess: () =>
      Promise.all([
        qc.invalidateQueries({ queryKey: ['me', 'orders', id] }),
        qc.invalidateQueries({ queryKey: ['me', 'orders'] }),
      ]),
  })

  const confirmMut = useMutation({
    mutationFn: () => confirmOrderReceived(id!),
    onSuccess: () =>
      Promise.all([
        qc.invalidateQueries({ queryKey: ['me', 'orders', id] }),
        qc.invalidateQueries({ queryKey: ['me', 'orders'] }),
      ]),
  })

  const msgMut = useMutation({
    mutationFn: () => postOrderMessage(id!, text.trim()),
    onSuccess: async () => {
      setText('')
      await qc.invalidateQueries({ queryKey: ['me', 'orders', id] })
      await qc.invalidateQueries({ queryKey: ['me', 'conversations'] })
    },
  })

  const order = orderQuery.data?.item
  const canSendMessage = text.replace(/<[^>]*>/g, ' ').trim().length > 0

  const eligibilityQuery = useQuery({
    queryKey: ['me', 'orders', id, 'review-eligibility'],
    queryFn: () => fetchOrderReviewEligibility(id!),
    enabled: Boolean(id && order?.status === 'DONE'),
  })

  const reviewMut = useMutation({
    mutationFn: async () => {
      if (!reviewTarget) return
      const t = reviewText.trim()
      await postProductReview(reviewTarget.productId, {
        rating: reviewRating,
        text: t.length ? t : null,
        imageUrl: reviewImageUrl,
      })
    },
    onSuccess: async () => {
      setReviewTarget(null)
      setReviewRating(5)
      setReviewText('')
      setReviewImageUrl(null)
      await qc.invalidateQueries({ queryKey: ['me', 'orders', id, 'review-eligibility'] })
    },
  })

  const uploadReviewImageMut = useMutation({
    mutationFn: (file: File) => uploadReviewImage(file),
    onSuccess: ({ url }) => setReviewImageUrl(url),
  })

  useEffect(() => {
    if (!id || orderQuery.status !== 'success' || !order) return
    void (async () => {
      await markOrderMessagesRead(id).catch(() => undefined)
      await qc.invalidateQueries({ queryKey: ['me', 'messages', 'unread-count'] })
    })()
  }, [id, order, orderQuery.status, qc])

  const address = useMemo((): AddressSnapshot | null => {
    if (!order?.addressSnapshotJson) return null
    try {
      return JSON.parse(order.addressSnapshotJson) as AddressSnapshot
    } catch {
      return null
    }
  }, [order])

  if (!id) return <Alert severity="error">Некорректный заказ.</Alert>
  if (orderQuery.isLoading) return <Typography>Загрузка…</Typography>
  if (orderQuery.isError || !order) return <Alert severity="error">Не удалось загрузить заказ.</Alert>

  return (
    <Box>
      <Stack direction={{ xs: 'column', sm: 'row' }} spacing={2} sx={{ mb: 2, alignItems: { sm: 'center' } }}>
        <Box sx={{ flexGrow: 1 }}>
          <Typography variant="h4">Заказ #{order.id.slice(-6)}</Typography>
          <Typography color="text.secondary">Статус: {orderStatusLabelRu(order.status)}</Typography>
        </Box>
        <Button component={RouterLink} to="/me/orders" variant="outlined">
          К списку
        </Button>
      </Stack>

      <Stack spacing={2} sx={{ maxWidth: 900 }}>
        <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
          <Typography variant="h6" gutterBottom>
            Позиции
          </Typography>
          <Stack spacing={1}>
            {order.items.map((i) => (
              <Stack key={i.id} direction="row" spacing={2} sx={{ alignItems: 'center' }}>
                <Box sx={{ flexGrow: 1 }}>
                  <Typography sx={{ fontWeight: 700 }}>{i.titleSnapshot}</Typography>
                  <Typography color="text.secondary" variant="body2">
                    {i.qty} × {formatPriceRub(i.priceCentsSnapshot)}
                  </Typography>
                </Box>
                <Typography sx={{ fontWeight: 700 }}>{formatPriceRub(i.priceCentsSnapshot * i.qty)}</Typography>
              </Stack>
            ))}
          </Stack>
          <Divider sx={{ my: 2 }} />
          <Stack spacing={0.25}>
            <Typography variant="body2" color="text.secondary">
              Товары: {formatPriceRub(order.itemsSubtotalCents)}
            </Typography>
            {order.deliveryType === 'delivery' && (
              <Typography variant="body2" color="text.secondary">
                Доставка: {formatPriceRub(order.deliveryFeeCents)}
              </Typography>
            )}
            <Typography variant="h6">Итого: {formatPriceRub(order.totalCents)}</Typography>
          </Stack>
        </Box>

        <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
          <Typography variant="h6" gutterBottom>
            Получение
          </Typography>
          <Typography color="text.secondary" variant="body2" sx={{ mb: 1 }}>
            Способ: {order.deliveryType === 'pickup' ? 'Самовывоз' : 'Доставка'}
          </Typography>
          {order.deliveryType === 'delivery' && (
            <>
              {address ? (
                <>
                  <Typography sx={{ fontWeight: 700 }}>{address.addressLine}</Typography>
                  <Typography color="text.secondary" variant="body2">
                    Получатель: {address.recipientName} · {address.recipientPhone}
                  </Typography>
                  {address.comment && (
                    <Typography color="text.secondary" variant="body2">
                      Комментарий: {address.comment}
                    </Typography>
                  )}
                </>
              ) : (
                <Typography color="text.secondary">Адрес не распознан.</Typography>
              )}
            </>
          )}
          {order.deliveryType === 'pickup' && (
            <Typography color="text.secondary">
              Адрес доставки не требуется. Мы свяжемся для согласования самовывоза.
            </Typography>
          )}
          {order.comment && (
            <Typography color="text.secondary" variant="body2" sx={{ mt: 1 }}>
              Комментарий к заказу: {order.comment}
            </Typography>
          )}
        </Box>

        <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
          <Typography variant="h6" gutterBottom>
            Оплата
          </Typography>
          {order.status === 'PENDING_PAYMENT' && (
            <>
              <Typography color="text.secondary" variant="body2" sx={{ mb: 1 }}>
                Пока это заглушка. После нажатия заказ перейдёт в статус «Проверка оплаты».
              </Typography>
              <Button variant="contained" onClick={() => payMut.mutate()} disabled={payMut.isPending}>
                Оплатить (заглушка)
              </Button>
            </>
          )}
          {order.status === 'PAYMENT_VERIFICATION' && (
            <Typography color="info.main" variant="body2">
              Оплата отправлена на проверку. Мы проверим поступление и обновим статус.
            </Typography>
          )}
          {!['PENDING_PAYMENT', 'PAYMENT_VERIFICATION'].includes(order.status) && (
            <Typography color="text.secondary" variant="body2">
              На этом этапе действий по оплате в этом блоке не требуется.
            </Typography>
          )}
        </Box>

        {(order.deliveryType === 'delivery' && order.status === 'SHIPPED') ||
        (order.deliveryType === 'pickup' && order.status === 'READY_FOR_PICKUP') ? (
          <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
            <Typography variant="h6" gutterBottom>
              Получение заказа
            </Typography>
            <Typography color="text.secondary" variant="body2" sx={{ mb: 2 }}>
              {order.deliveryType === 'delivery'
                ? 'Когда забрали посылку у курьера или на пункте выдачи — подтвердите получение.'
                : 'Когда забрали заказ самовывозом — подтвердите получение.'}
            </Typography>
            <Button
              variant="contained"
              color="success"
              onClick={() => confirmMut.mutate()}
              disabled={confirmMut.isPending}
            >
              Подтвердить получение
            </Button>
          </Box>
        ) : null}

        {order.status === 'DONE' && eligibilityQuery.isSuccess && eligibilityQuery.data.canReview && (
          <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
            <Typography variant="h6" gutterBottom>
              Отзывы
            </Typography>
            <Typography color="text.secondary" variant="body2" sx={{ mb: 2 }}>
              Поделитесь впечатлением о товарах. Отзывы появляются после модерации.
            </Typography>
            <Stack spacing={1}>
              {eligibilityQuery.data.items.map((row) => (
                <Stack
                  key={row.productId}
                  direction={{ xs: 'column', sm: 'row' }}
                  spacing={1}
                  sx={{ alignItems: { sm: 'center' }, justifyContent: 'space-between' }}
                >
                  <Typography sx={{ flexGrow: 1 }}>{row.title}</Typography>
                  <Button
                    size="small"
                    variant="outlined"
                    disabled={row.hasReview}
                    onClick={() => setReviewTarget({ productId: row.productId, title: row.title })}
                  >
                    {row.hasReview ? 'Отзыв отправлен' : 'Оставить отзыв'}
                  </Button>
                </Stack>
              ))}
            </Stack>
          </Box>
        )}

        <Box sx={{ border: 1, borderColor: 'divider', borderRadius: 2, p: 2, bgcolor: 'background.paper' }}>
          <Typography variant="h6" gutterBottom>
            Чат по заказу
          </Typography>
          <Stack spacing={1} sx={{ mb: 2 }}>
            {order.messages.map((m) => (
              <Box
                key={m.id}
                sx={{
                  p: 1.25,
                  borderRadius: 2,
                  bgcolor: m.authorType === 'admin' ? 'grey.100' : 'primary.50',
                  border: 1,
                  borderColor: 'divider',
                  alignSelf: m.authorType === 'admin' ? 'flex-start' : 'flex-end',
                  width: 'fit-content',
                  maxWidth: '85%',
                }}
              >
                <Typography variant="caption" color="text.secondary">
                  {m.authorType === 'admin' ? 'Админ' : 'Вы'} · {new Date(m.createdAt).toLocaleString()}
                </Typography>
                <RichTextMessageContent value={m.text} />
              </Box>
            ))}
            {order.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={text} onChange={setText} placeholder="Сообщение" />
            </Box>
            <Button
              variant="contained"
              onClick={() => msgMut.mutate()}
              disabled={msgMut.isPending || !canSendMessage}
              sx={{ minWidth: 160 }}
            >
              Отправить
            </Button>
          </Stack>
        </Box>
      </Stack>

      <Dialog
        open={Boolean(reviewTarget)}
        onClose={() => {
          if (reviewMut.isPending) return
          setReviewTarget(null)
          setReviewRating(5)
          setReviewText('')
          setReviewImageUrl(null)
        }}
        fullWidth
        maxWidth="sm"
      >
        <DialogTitle>Отзыв: {reviewTarget?.title}</DialogTitle>
        <DialogContent>
          <Typography variant="body2" color="text.secondary" sx={{ mb: 1 }}>
            Оценка
          </Typography>
          <Rating
            value={reviewRating}
            onChange={(_, v) => {
              if (v !== null) setReviewRating(v)
            }}
          />
          <Box sx={{ mt: 2 }}>
            <RichTextMessageEditor
              value={reviewText}
              onChange={setReviewText}
              placeholder="Комментарий (необязательно)"
            />
          </Box>
          <Stack direction={{ xs: 'column', sm: 'row' }} spacing={1.5} sx={{ mt: 2, alignItems: { sm: 'center' } }}>
            <Button component="label" variant="outlined" disabled={uploadReviewImageMut.isPending}>
              {reviewImageUrl ? 'Заменить фото' : 'Прикрепить фото'}
              <input
                hidden
                type="file"
                accept="image/png,image/jpeg,image/webp"
                onChange={(e) => {
                  const file = e.target.files?.[0]
                  if (!file) return
                  uploadReviewImageMut.mutate(file)
                  e.currentTarget.value = ''
                }}
              />
            </Button>
            {reviewImageUrl && (
              <Button
                color="error"
                variant="text"
                onClick={() => setReviewImageUrl(null)}
                disabled={reviewMut.isPending}
              >
                Удалить фото
              </Button>
            )}
          </Stack>
          {reviewImageUrl && (
            <Box
              component="img"
              src={reviewImageUrl}
              alt="Фото к отзыву"
              sx={{
                mt: 1,
                width: 120,
                height: 120,
                objectFit: 'cover',
                borderRadius: 1.5,
                border: 1,
                borderColor: 'divider',
              }}
            />
          )}
          {uploadReviewImageMut.isError && (
            <Alert severity="error" sx={{ mt: 2 }}>
              Не удалось загрузить фото. Разрешены png, jpg, jpeg, webp.
            </Alert>
          )}
          {reviewMut.isError && (
            <Alert severity="error" sx={{ mt: 2 }}>
              {reviewSubmitErrorMessage(reviewMut.error)}
            </Alert>
          )}
        </DialogContent>
        <DialogActions>
          <Button
            onClick={() => {
              setReviewTarget(null)
              setReviewRating(5)
              setReviewText('')
              setReviewImageUrl(null)
            }}
            disabled={reviewMut.isPending}
          >
            Отмена
          </Button>
          <Button variant="contained" disabled={reviewMut.isPending} onClick={() => reviewMut.mutate()}>
            Отправить
          </Button>
        </DialogActions>
      </Dialog>
    </Box>
  )
}
