import { useEffect, useMemo } from 'react'
import Alert from '@mui/material/Alert'
import Box from '@mui/material/Box'
import Button from '@mui/material/Button'
import Divider from '@mui/material/Divider'
import Link from '@mui/material/Link'
import Stack from '@mui/material/Stack'
import Typography from '@mui/material/Typography'
import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { Link as RouterLink, useNavigate, useParams, useSearchParams } from 'react-router-dom'
import {
  confirmOrderReceived,
  createOrderPayment,
  fetchMyOrder,
  getOrderPaymentStatus,
  postOrderMessage,
  fetchOrderReviewEligibility,
} from '@/entities/order/api/order-api'
import { postProductReview, uploadReviewImage } from '@/entities/review/api/reviews-api'
import { markOrderMessagesRead } from '@/entities/user/api/messages-api'
import { OrderChat } from '@/features/order-chat'
import { OrderPaymentSection } from '@/features/order-payment'
import { ReviewSection } from '@/features/product-review'
import { deliveryCarrierLabelRu } from '@/shared/constants/delivery-carrier'
import { PICKUP_ADDRESS_FULL } from '@/shared/constants/pickup-point'
import { formatPriceRub } from '@/shared/lib/format-price'
import { parseOrderAddressSnapshot } from '@/shared/lib/order-address-snapshot'
import { orderStatusLabelRu } from '@/shared/lib/order-status-labels'

export function OrderDetailPage() {
  const { id } = useParams()
  const qc = useQueryClient()
  const navigate = useNavigate()

  const [searchParams] = useSearchParams()
  const paidParam = searchParams.get('paid')

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

  const payMut = useMutation({
    mutationFn: () => createOrderPayment(id!),
    onSuccess: async (data) => {
      window.location.href = data.confirmationUrl
    },
  })

  const paymentStatusQuery = useQuery({
    queryKey: ['me', 'orders', id, 'payment-status'],
    queryFn: () => getOrderPaymentStatus(id!),
    enabled: Boolean(id && paidParam === '1'),
    refetchInterval: (query) => {
      const data = query.state.data
      if (data && (data.paid || data.status === 'canceled')) return false
      return 3000
    },
  })

  useEffect(() => {
    const data = paymentStatusQuery.data
    if (data && (data.paid || data.status === 'canceled') && paidParam === '1') {
      qc.invalidateQueries({ queryKey: ['me', 'orders', id] })
      navigate(`/me/orders/${id}`, { replace: true })
    }
  }, [paymentStatusQuery.data, paidParam, qc, id, navigate])

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

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

  const order = orderQuery.data?.item

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

  const reviewMut = useMutation({
    mutationFn: async (params: { productId: string; rating: number; text: string; imageUrl: string | null }) => {
      await postProductReview(params.productId, {
        rating: params.rating,
        text: params.text.length ? params.text : null,
        imageUrl: params.imageUrl,
      })
    },
    onSuccess: async () => {
      await qc.invalidateQueries({ queryKey: ['me', 'orders', id, 'review-eligibility'] })
    },
  })

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

  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(() => parseOrderAddressSnapshot(order?.addressSnapshotJson), [order?.addressSnapshotJson])

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

  const payOnPickup = (order.paymentMethod ?? 'online') === 'on_pickup'

  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>

      {paidParam === '1' && paymentStatusQuery.data && (
        <Alert
          severity={
            paymentStatusQuery.data.paid
              ? 'success'
              : paymentStatusQuery.data.status === 'canceled'
                ? 'warning'
                : 'info'
          }
          sx={{ mb: 2 }}
        >
          {paymentStatusQuery.data.paid
            ? 'Оплата прошла успешно!'
            : paymentStatusQuery.data.status === 'canceled'
              ? 'Оплата отмена. Вы можете попробовать снова.'
              : 'Ожидаем подтверждения оплаты…'}
        </Alert>
      )}

      <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' ? 'Самовывоз' : 'Доставка'}
            {order.deliveryType === 'pickup' && <> · оплата: {payOnPickup ? 'при получении' : 'онлайн'}</>}
          </Typography>
          {order.deliveryType === 'delivery' && deliveryCarrierLabelRu(order.deliveryCarrier) && (
            <Typography variant="body2" sx={{ mb: 1 }}>
              Служба: {deliveryCarrierLabelRu(order.deliveryCarrier)}
            </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' && (
            <Stack spacing={0.75}>
              <Typography color="text.secondary" variant="body2">
                Адрес самовывоза и карта — на странице{' '}
                <Link component={RouterLink} to="/about" underline="hover">
                  О нас
                </Link>
                .
              </Typography>
              <Typography variant="body2" sx={{ fontWeight: 600 }}>
                {PICKUP_ADDRESS_FULL}
              </Typography>
              <Typography color="text.secondary" variant="body2">
                Заберите заказ ко времени, которое согласуем в чате заказа.
              </Typography>
            </Stack>
          )}
          {order.comment && (
            <Typography color="text.secondary" variant="body2" sx={{ mt: 1 }}>
              Комментарий к заказу: {order.comment}
            </Typography>
          )}
        </Box>

        <OrderPaymentSection
          status={order.status}
          deliveryFeeLocked={order.deliveryFeeLocked}
          paymentMethod={order.paymentMethod ?? null}
          totalCents={order.totalCents}
          isPayPending={payMut.isPending}
          payError={payMut.error}
          onPay={() => payMut.mutate()}
        />

        {(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 && (
          <ReviewSection
            items={eligibilityQuery.data.items}
            isSubmitPending={reviewMut.isPending}
            isUploadPending={uploadReviewImageMut.isPending}
            submitError={reviewMut.error}
            uploadError={uploadReviewImageMut.error}
            onSubmitReview={async (params) => {
              await reviewMut.mutateAsync(params)
            }}
            onUploadImage={async (file) => {
              const result = await uploadReviewImageMut.mutateAsync(file)
              return result
            }}
          />
        )}

        <OrderChat messages={order.messages} isPending={msgMut.isPending} onSend={(text) => msgMut.mutate(text)} />
      </Stack>
    </Box>
  )
}
