import { useEffect, useMemo, useState } from 'react'
import { useNavigate } from 'react-router-dom'
import { Minus, Package, Plus, ShoppingBag, Trash2 } from 'lucide-react'
import { useToast } from '@meshkee/dashboard-ui'
import { useAuth } from '../../context/AuthContext'
import { ApiError, isAbortError } from '../../lib/api'
import {
  loadGuestCart,
  saveGuestCart,
  type GuestCartItem,
} from '../../lib/guestCart'
import {
  getCart,
  removeCartItem,
  updateCartItem,
  type Cart,
} from '../../services/cartService'
import { syncGuestCartToServer } from '../../services/syncGuestCart'
import { formatIrtPrice } from '../../utils/irtPrice'
import { CheckoutActionBar } from '../../components/checkout/CheckoutActionBar'
import styles from './CheckoutSteps.module.css'

type DisplayItem = {
  id: string
  title: string
  variant?: string
  image: string | null
  quantity: number
  lineTotal: number
  stockQuantity: number | null
}

function guestToDisplay(items: GuestCartItem[]): DisplayItem[] {
  return items.map((item) => ({
    id: item.id,
    title: item.name,
    image: item.image,
    quantity: item.quantity,
    lineTotal: item.price * item.quantity,
    stockQuantity: null,
  }))
}

function formatVariantLabel(item: Cart['items'][number]): string | undefined {
  if (item.selections.length > 0) {
    return item.selections.map((selection) => selection.value).join(' · ')
  }

  const title = item.productNameFa?.trim() || item.productTitle
  if (item.label && item.label !== title && item.label !== item.productTitle) {
    return item.label
  }

  return undefined
}

function apiToDisplay(cart: Cart): DisplayItem[] {
  return cart.items.map((item) => ({
    id: item.id,
    title: item.productNameFa?.trim() || item.productTitle,
    variant: formatVariantLabel(item),
    image: item.productImage,
    quantity: item.quantity,
    lineTotal: item.lineTotal,
    stockQuantity: item.stockQuantity,
  }))
}

export function CheckoutCartStep() {
  const navigate = useNavigate()
  const { showToast } = useToast()
  const { user } = useAuth()
  const isAuthenticated = Boolean(user)

  const [cart, setCart] = useState<Cart | null>(null)
  const [guestItems, setGuestItems] = useState<GuestCartItem[]>([])
  const [loading, setLoading] = useState(true)
  const [error, setError] = useState('')
  const [busyItemId, setBusyItemId] = useState<string | null>(null)

  useEffect(() => {
    const controller = new AbortController()

    async function load() {
      setLoading(true)
      setError('')

      const guest = loadGuestCart()
      setGuestItems(guest)

      if (!isAuthenticated) {
        setCart(null)
        setLoading(false)
        return
      }

      try {
        let data = await getCart(controller.signal)
        if (controller.signal.aborted) return

        if (data.cart.items.length === 0 && guest.length > 0) {
          const synced = await syncGuestCartToServer(controller.signal)
          if (controller.signal.aborted) return
          data = { cart: synced }
        }

        setCart(data.cart)
        if ((data.cart?.items?.length ?? 0) > 0) {
          setGuestItems([])
        }
      } catch (err) {
        if (isAbortError(err)) return
        setError(err instanceof ApiError ? err.message : 'بارگذاری سبد خرید ممکن نشد.')
      } finally {
        if (!controller.signal.aborted) setLoading(false)
      }
    }

    void load()
    return () => controller.abort()
  }, [isAuthenticated])

  const apiHasItems = (cart?.items.length ?? 0) > 0
  const usingGuest = !isAuthenticated || !apiHasItems

  const items = useMemo(
    () => (usingGuest ? guestToDisplay(guestItems) : cart ? apiToDisplay(cart) : []),
    [usingGuest, guestItems, cart],
  )

  const subtotal = useMemo(
    () => items.reduce((sum, item) => sum + item.lineTotal, 0),
    [items],
  )

  const totalQuantity = useMemo(
    () => items.reduce((sum, item) => sum + item.quantity, 0),
    [items],
  )

  function persistGuest(next: GuestCartItem[]) {
    setGuestItems(next)
    saveGuestCart(next)
  }

  async function handleQuantityChange(itemId: string, nextQuantity: number) {
    if (usingGuest) {
      if (nextQuantity <= 0) {
        persistGuest(guestItems.filter((item) => item.id !== itemId))
        return
      }
      persistGuest(
        guestItems.map((item) =>
          item.id === itemId ? { ...item, quantity: nextQuantity } : item,
        ),
      )
      return
    }

    setBusyItemId(itemId)
    try {
      const data = await updateCartItem(itemId, nextQuantity)
      setCart(data.cart)
    } catch (err) {
      showToast(err instanceof ApiError ? err.message : 'به‌روزرسانی تعداد ممکن نشد.', 'error')
    } finally {
      setBusyItemId(null)
    }
  }

  async function handleRemove(itemId: string) {
    if (usingGuest) {
      persistGuest(guestItems.filter((item) => item.id !== itemId))
      showToast('محصول از سبد حذف شد.', 'success')
      return
    }

    setBusyItemId(itemId)
    try {
      const data = await removeCartItem(itemId)
      setCart(data.cart)
      showToast('محصول از سبد حذف شد.', 'success')
    } catch (err) {
      showToast(err instanceof ApiError ? err.message : 'حذف محصول ممکن نشد.', 'error')
    } finally {
      setBusyItemId(null)
    }
  }

  async function handleContinue() {
    if (!isAuthenticated) {
      navigate(`/checkout/login?redirect=${encodeURIComponent('/checkout/delivery')}`, {
        state: { from: '/checkout/delivery' },
      })
      return
    }

    if (usingGuest && guestItems.length > 0) {
      setLoading(true)
      try {
        const cart = await syncGuestCartToServer()
        setCart(cart)
        setGuestItems([])
        if (cart.items.length === 0) {
          showToast('انتقال سبد خرید ممکن نشد. دوباره تلاش کنید.', 'error')
          return
        }
      } catch (err) {
        showToast(
          err instanceof ApiError ? err.message : 'انتقال سبد خرید ممکن نشد.',
          'error',
        )
        return
      } finally {
        setLoading(false)
      }
    }

    navigate('/checkout/delivery')
  }

  if (loading) {
    return <div className={styles.loading}>در حال بارگذاری سبد خرید...</div>
  }

  if (error && items.length === 0) {
    return (
      <div className={styles.stepContent}>
        <div className={styles.error} role="alert">
          {error}
        </div>
        <button type="button" className={styles.secondaryBtn} onClick={() => window.location.reload()}>
          تلاش مجدد
        </button>
      </div>
    )
  }

  return (
    <div className={styles.stepContent}>
      <div>
        <h1 className={styles.stepTitle}>سبد خرید شما</h1>
        <p className={styles.stepDesc}>
          {items.length === 0
            ? 'سبد خرید شما خالی است.'
            : 'آماده تکمیل سفارش هستید.'}
          {!isAuthenticated && items.length > 0
            ? ' برای ادامه، در مرحله بعد وارد شوید.'
            : ''}
        </p>
      </div>

      {items.length === 0 ? (
        <div className={styles.empty}>
          <div className={styles.emptyIcon}>
            <ShoppingBag size={40} strokeWidth={1.5} />
          </div>
          <p>برای شروع خرید، از فروشگاه محصول اضافه کنید.</p>
        </div>
      ) : (
        <div className={styles.cartList}>
          {items.map((item) => {
            const busy = busyItemId === item.id
            const atMax =
              item.stockQuantity !== null && item.quantity >= item.stockQuantity

            return (
              <article key={item.id} className={styles.cartItem}>
                {item.image ? (
                  <img src={item.image} alt="" className={styles.cartItemImage} />
                ) : (
                  <div className={`${styles.cartItemImage} ${styles.cartItemImagePlaceholder}`}>
                    <Package size={22} />
                  </div>
                )}

                <div className={styles.cartItemInfo}>
                  <div className={styles.cartItemTitle}>{item.title}</div>
                  {item.variant ? (
                    <div className={styles.cartItemVariant}>{item.variant}</div>
                  ) : null}
                </div>

                <div className={styles.cartItemFooter}>
                  <button
                    type="button"
                    className={styles.removeBtn}
                    onClick={() => void handleRemove(item.id)}
                    disabled={busy}
                    aria-label="حذف محصول"
                  >
                    <Trash2 size={14} />
                  </button>
                  <div className={styles.qtyControls}>
                    <button
                      type="button"
                      className={styles.qtyBtn}
                      onClick={() => void handleQuantityChange(item.id, item.quantity - 1)}
                      disabled={busy || item.quantity <= 1}
                      aria-label="کاهش تعداد"
                    >
                      <Minus size={14} />
                    </button>
                    <span className={styles.qtyValue}>{item.quantity}</span>
                    <button
                      type="button"
                      className={styles.qtyBtn}
                      onClick={() => void handleQuantityChange(item.id, item.quantity + 1)}
                      disabled={busy || atMax}
                      aria-label="افزایش تعداد"
                    >
                      <Plus size={14} />
                    </button>
                  </div>
                  <span className={styles.cartItemPrice}>{formatIrtPrice(item.lineTotal)}</span>
                </div>
              </article>
            )
          })}
        </div>
      )}

      {items.length > 0 && (
        <>
          <div className={styles.summary}>
            <div className={styles.summaryRow}>
              <span>تعداد کالا</span>
              <span>{totalQuantity.toLocaleString('fa-IR')} عدد</span>
            </div>
            <div className={`${styles.summaryRow} ${styles.summaryRowTotal}`}>
              <span>جمع کل</span>
              <span className={styles.priceEn}>{formatIrtPrice(subtotal)}</span>
            </div>
          </div>

          <CheckoutActionBar
            primaryLabel={isAuthenticated ? 'ادامه به ارسال' : 'ادامه به ورود'}
            onPrimary={handleContinue}
          />
        </>
      )}
    </div>
  )
}
