import { useEffect, useMemo, useState } from 'react'
import { useQuery } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import { Truck, Store as StoreIcon, CalendarDays, Clock, Sparkles, MapPin, CheckCircle2, AlertTriangle } from 'lucide-react'
import {
  getCart, getStores, getAvailability, getHolidays, addressVerify, taxQuote,
  getLoyaltyMe, checkout, createPayment,
} from '../api/client'
import { money, useShop } from '../store/shop'
import { PaymentSection, PayMethod } from './components/payments'
import { BRAND } from './brand'

function nextDays(n: number) {
  const out: string[] = []
  const d = new Date()
  for (let i = 0; i < n; i++) { const x = new Date(d); x.setDate(d.getDate() + i); out.push(x.toISOString().slice(0, 10)) }
  return out
}

export default function Checkout() {
  const nav = useNavigate()
  const { custToken, storeId: ctxStoreId, zip: ctxZip, setCartCount } = useShop()
  const [fulfillment, setFulfillment] = useState<'DELIVERY' | 'PICKUP'>('DELIVERY')
  const [storeId, setStoreId] = useState<number>(ctxStoreId || 0)
  const [date, setDate] = useState('')
  const [slot, setSlot] = useState<{ id: number; label: string } | null>(null)
  const [receiverName, setReceiverName] = useState('')
  const [receiverPhone, setReceiverPhone] = useState('')
  const [address, setAddress] = useState('')
  const [deliveryZip, setDeliveryZip] = useState(ctxZip || '')
  const [cardMessage, setCardMessage] = useState('')
  const [memo, setMemo] = useState('')
  const [usePointsAmt, setUsePointsAmt] = useState(0)
  const [payMethod, setPayMethod] = useState<PayMethod>('CARD')
  const [card, setCard] = useState<{ last4: string; expiry: string; complete: boolean }>({ last4: '', expiry: '', complete: false })
  const [addrCheck, setAddrCheck] = useState<any>(null)
  const [tax, setTax] = useState<any>(null)
  const [placing, setPlacing] = useState(false)
  const [done, setDone] = useState<any>(null)
  const [err, setErr] = useState('')

  const { data: cart } = useQuery({ queryKey: ['cart'], queryFn: getCart, enabled: !!custToken })
  const { data: stores } = useQuery({ queryKey: ['stores'], queryFn: () => getStores(true) })
  const { data: loyalty } = useQuery({ queryKey: ['loyalty-me'], queryFn: getLoyaltyMe, enabled: !!custToken })
  const { data: holidays } = useQuery({ queryKey: ['holidays'], queryFn: getHolidays })
  const { data: avail } = useQuery({
    queryKey: ['avail', storeId, date],
    queryFn: () => getAvailability(storeId, date),
    enabled: !!storeId && !!date,
  })

  useEffect(() => { if (!storeId && stores?.length) setStoreId(stores[0].id) }, [stores])

  const items = cart || []
  const subtotal = items.reduce((s: number, i: any) => s + (i.price || (i.unitPrice || 0) * (i.quantity || 1)), 0)
  const surge = avail?.surgeMultiplier && avail.surgeMultiplier > 1 ? subtotal * (avail.surgeMultiplier - 1) : 0
  const discountRate = loyalty?.benefit?.discountRate || 0
  const tierDiscount = subtotal * (discountRate / 100)
  const taxAmount = tax?.taxAmount || 0
  const pointBalance = loyalty?.pointBalance || 0
  const maxUsablePoints = Math.min(pointBalance, Math.floor(subtotal))
  const grand = Math.max(0, subtotal + surge + taxAmount - tierDiscount - usePointsAmt)

  const holidaySet = useMemo(() => new Set((holidays || []).filter((h: any) => h.blocked).map((h: any) => h.holidayDate)), [holidays])

  const verifyAddr = async () => {
    if (!address || !deliveryZip) return
    const r = await addressVerify(address, deliveryZip).catch(() => null)
    setAddrCheck(r)
  }
  const quoteTax = async () => {
    const st = stores?.find((s: any) => s.id === storeId)?.state || ''
    const r = await taxQuote(subtotal, deliveryZip || '', st).catch(() => null)
    setTax(r)
  }
  useEffect(() => { if (subtotal > 0 && storeId) quoteTax() }, [subtotal, storeId, deliveryZip])

  const placeOrder = async () => {
    setErr('')
    if (!custToken) { nav('/account'); return }
    if (!items.length) { setErr('장바구니가 비어 있습니다.'); return }
    if (!date || !slot) { setErr('배송/픽업 날짜와 시간대를 선택하세요.'); return }
    if (fulfillment === 'DELIVERY' && (!address || !receiverName)) { setErr('받는 분과 주소를 입력하세요.'); return }
    if (payMethod === 'CARD' && !card.complete) { setErr('카드 정보를 입력하세요.'); return }
    setPlacing(true)
    try {
      const order = await checkout({
        storeId, fulfillmentType: fulfillment, receiverName, receiverPhone,
        address: fulfillment === 'DELIVERY' ? address : '', deliveryZip,
        scheduledDate: date, slotId: slot.id, slotLabel: slot.label,
        cardMessage, memo, couponId: null,
        discountAmount: Math.round((tierDiscount + usePointsAmt) * 100) / 100,
        taxAmount, surgeAmount: Math.round(surge * 100) / 100,
      })
      // 결제 게이트웨이 경유 (mock/Stripe) — 카드 전체번호 미보관, 마지막 4자리만 참조용 전달
      await createPayment({
        orderId: order.id, amount: grand, method: payMethod, usePoints: usePointsAmt,
        cardLast4: payMethod === 'CARD' ? card.last4 : '',
      }).catch(() => {})
      setCartCount(0)
      setDone(order)
    } catch (e: any) {
      setErr(e?.response?.data?.message || '주문에 실패했습니다. 잠시 후 다시 시도하세요.')
    } finally { setPlacing(false) }
  }

  if (!custToken) { nav('/account'); return null }

  if (done) return (
    <div className="max-w-lg mx-auto px-4 py-20 text-center">
      <CheckCircle2 className="mx-auto text-leaf mb-4" size={56} />
      <h1 className="font-serif text-2xl font-bold mb-2">주문이 접수되었습니다</h1>
      <p className="text-gray-500 mb-1">주문번호 <span className="font-semibold text-bloom2">{done.orderNo || `#${done.id}`}</span></p>
      <p className="text-sm text-gray-500 mb-6">{date} · {slot?.label} · {money(grand)}</p>
      <div className="flex gap-3 justify-center">
        <button onClick={() => nav('/orders')} className="bg-bloom text-white px-6 py-2.5 rounded-full font-semibold">주문 내역</button>
        <button onClick={() => nav('/home')} className="border border-blush-100 px-6 py-2.5 rounded-full text-bloom2">계속 쇼핑</button>
      </div>
    </div>
  )

  return (
    <div className="max-w-5xl mx-auto px-4 py-8">
      <h1 className="font-serif text-2xl font-bold mb-6">주문 / 결제</h1>
      <div className="grid md:grid-cols-3 gap-6">
        <div className="md:col-span-2 space-y-5">
          {/* 수령 방식 */}
          <section className="bg-white rounded-2xl border border-blush-100/60 p-5">
            <div className="text-sm font-semibold mb-3">수령 방식</div>
            <div className="grid grid-cols-2 gap-3">
              <button onClick={() => setFulfillment('DELIVERY')} className={`flex items-center gap-2 justify-center py-3 rounded-xl border ${fulfillment === 'DELIVERY' ? 'border-bloom bg-petal text-bloom2' : 'border-blush-100'}`}><Truck size={18} /> 로컬 배송</button>
              <button onClick={() => setFulfillment('PICKUP')} className={`flex items-center gap-2 justify-center py-3 rounded-xl border ${fulfillment === 'PICKUP' ? 'border-bloom bg-petal text-bloom2' : 'border-blush-100'}`}><StoreIcon size={18} /> 매장 픽업</button>
            </div>
            <div className="mt-3">
              <label className="block text-xs text-gray-500 mb-1">매장</label>
              <select value={storeId} onChange={e => setStoreId(Number(e.target.value))} className="w-full px-3 py-2 rounded-xl border border-blush-100 text-sm bg-white">
                {(stores || []).map((s: any) => <option key={s.id} value={s.id}>{s.name} ({s.city}, {s.state})</option>)}
              </select>
            </div>
          </section>

          {/* 날짜 + 타임슬롯 (UrbanStems/Ode) */}
          <section className="bg-white rounded-2xl border border-blush-100/60 p-5">
            <div className="flex items-center gap-2 text-sm font-semibold mb-3"><CalendarDays size={16} className="text-bloom" /> 배송/픽업 날짜</div>
            <div className="flex gap-2 overflow-x-auto pb-2">
              {nextDays(14).map(d => {
                const blocked = holidaySet.has(d)
                const sel = date === d
                const dd = new Date(d)
                return (
                  <button key={d} disabled={blocked} onClick={() => { setDate(d); setSlot(null) }}
                    className={`shrink-0 w-16 py-2 rounded-xl border text-center text-xs ${blocked ? 'opacity-30 cursor-not-allowed border-blush-100' : sel ? 'border-bloom bg-bloom text-white' : 'border-blush-100 hover:border-bloom'}`}>
                    <div className="font-semibold">{dd.toLocaleDateString('en-US', { weekday: 'short' })}</div>
                    <div className="text-base">{dd.getDate()}</div>
                    {blocked && <div className="text-[9px]">휴무</div>}
                  </button>
                )
              })}
            </div>
            {date && avail && (
              <div className="mt-3">
                {avail.blocked && <div className="flex items-center gap-1.5 text-blush-500 text-xs mb-2"><AlertTriangle size={13} /> 해당일은 배송이 차단되었습니다(피크시즌/휴무).</div>}
                {avail.surgeMultiplier > 1 && <div className="text-xs text-amber-600 mb-2">⚡ 성수기 서지 프라이싱 ×{avail.surgeMultiplier} 적용</div>}
                {avail.sameDayAvailable && <div className="text-xs text-leaf mb-2">당일배송 가능 (마감 {avail.sameDayCutoff})</div>}
                <div className="flex items-center gap-2 text-sm font-medium mb-2"><Clock size={14} className="text-bloom" /> 시간대</div>
                <div className="grid grid-cols-3 gap-2">
                  {(avail.slots || []).map((s: any) => {
                    const full = s.available === false || (s.capacity != null && s.booked >= s.capacity)
                    return (
                      <button key={s.id} disabled={full} onClick={() => setSlot({ id: s.id, label: s.slotLabel })}
                        className={`py-2 rounded-lg border text-xs ${full ? 'opacity-30 cursor-not-allowed' : slot?.id === s.id ? 'border-bloom bg-petal text-bloom2 font-semibold' : 'border-blush-100 hover:border-bloom'}`}>
                        {s.slotLabel}
                      </button>
                    )
                  })}
                  {!(avail.slots || []).length && <div className="col-span-3 text-gray-400 text-xs py-2">예약 가능한 시간대가 없습니다.</div>}
                </div>
              </div>
            )}
          </section>

          {/* 받는 분 / 주소 (배송) */}
          {fulfillment === 'DELIVERY' && (
            <section className="bg-white rounded-2xl border border-blush-100/60 p-5 space-y-3">
              <div className="text-sm font-semibold">받는 분 정보</div>
              <div className="grid grid-cols-2 gap-3">
                <input value={receiverName} onChange={e => setReceiverName(e.target.value)} placeholder="받는 분 이름" className="px-3 py-2 rounded-xl border border-blush-100 text-sm outline-none focus:border-bloom" />
                <input value={receiverPhone} onChange={e => setReceiverPhone(e.target.value)} placeholder="연락처" className="px-3 py-2 rounded-xl border border-blush-100 text-sm outline-none focus:border-bloom" />
              </div>
              <div className="flex gap-2">
                <input value={address} onChange={e => setAddress(e.target.value)} placeholder="배송 주소" className="flex-1 px-3 py-2 rounded-xl border border-blush-100 text-sm outline-none focus:border-bloom" />
                <input value={deliveryZip} onChange={e => setDeliveryZip(e.target.value.replace(/\D/g, '').slice(0, 5))} placeholder="ZIP" className="w-24 px-3 py-2 rounded-xl border border-blush-100 text-sm text-center outline-none focus:border-bloom" />
                <button onClick={verifyAddr} className="px-3 rounded-xl border border-bloom text-bloom text-sm font-semibold flex items-center gap-1"><MapPin size={14} /> 검증</button>
              </div>
              {addrCheck && (
                <div className={`text-xs ${addrCheck.valid ? 'text-leaf' : 'text-blush-500'}`}>
                  {addrCheck.valid ? `검증됨: ${addrCheck.normalized || address} (${addrCheck.provider})` : `주소 검증 실패 (${addrCheck.provider})`}
                </div>
              )}
            </section>
          )}

          {/* 카드 메시지 / 메모 */}
          <section className="bg-white rounded-2xl border border-blush-100/60 p-5 space-y-3">
            <div className="flex items-center justify-between"><div className="text-sm font-semibold">카드 메시지</div><span className="text-xs text-bloom flex items-center gap-1"><Sparkles size={12} /> AI 작성은 상품 페이지에서</span></div>
            <textarea value={cardMessage} onChange={e => setCardMessage(e.target.value)} rows={2} maxLength={200} placeholder="받는 분께 전할 메시지" className="w-full px-3 py-2 rounded-xl border border-blush-100 text-sm outline-none focus:border-bloom" />
            <input value={memo} onChange={e => setMemo(e.target.value)} placeholder="배송 요청사항 (선택)" className="w-full px-3 py-2 rounded-xl border border-blush-100 text-sm outline-none focus:border-bloom" />
          </section>

          {/* 결제수단 (Montvale: Visa·Mastercard·Amex·Discover·Apple Pay·Google Pay) */}
          <section className="bg-white rounded-2xl border border-blush-100/60 p-5">
            <div className="text-sm font-semibold mb-3">결제수단 (Payment)</div>
            <PaymentSection
              method={payMethod}
              onMethod={setPayMethod}
              onCardChange={setCard}
              cards={BRAND.cards}
              wallets={BRAND.wallets}
            />
          </section>
        </div>

        {/* 요약 */}
        <aside className="bg-white rounded-2xl border border-blush-100/60 p-5 h-fit sticky top-20">
          <div className="text-sm font-semibold mb-3">주문 요약</div>
          <div className="space-y-1.5 text-sm">
            <Row k="소계" v={money(subtotal)} />
            {surge > 0 && <Row k="서지 프라이싱" v={`+${money(surge)}`} amber />}
            <Row k="세금" v={money(taxAmount)} sub={tax ? `${tax.provider} ${(tax.rate * 100).toFixed(1)}%` : ''} />
            {tierDiscount > 0 && <Row k={`등급 할인(${loyalty?.tierName || ''} ${discountRate}%)`} v={`-${money(tierDiscount)}`} green />}
            {usePointsAmt > 0 && <Row k="포인트 사용" v={`-${money(usePointsAmt)}`} green />}
          </div>

          {/* 마일리지/포인트 */}
          {!!custToken && (
            <div className="mt-4 bg-petal rounded-xl p-3">
              <div className="flex items-center justify-between text-xs text-bloom2 mb-1">
                <span>포인트 보유 {pointBalance.toLocaleString()}P</span>
                <button onClick={() => setUsePointsAmt(maxUsablePoints)} className="text-bloom font-semibold">전액 사용</button>
              </div>
              <input type="range" min={0} max={maxUsablePoints} value={usePointsAmt} onChange={e => setUsePointsAmt(Number(e.target.value))} className="w-full accent-bloom" />
              <div className="text-xs text-gray-500 text-right">{usePointsAmt.toLocaleString()}P 사용</div>
            </div>
          )}

          <div className="border-t border-blush-100/60 mt-4 pt-3 flex justify-between font-bold text-base">
            <span>결제 금액</span><span className="text-bloom2">{money(grand)}</span>
          </div>
          {err && <div className="text-blush-500 text-xs mt-3">{err}</div>}
          <button onClick={placeOrder} disabled={placing} className="w-full mt-4 bg-bloom text-white font-semibold py-3 rounded-full hover:bg-bloom2 disabled:opacity-60">
            {placing ? '결제 중…' : `${money(grand)} 결제하기`}
          </button>
          <p className="text-[11px] text-gray-400 text-center mt-2">결제는 GUARDiA PaymentGateway(보안 어댑터) 경유 · 카드정보 비저장</p>
        </aside>
      </div>
    </div>
  )
}

function Row({ k, v, sub, amber, green }: { k: string; v: string; sub?: string; amber?: boolean; green?: boolean }) {
  return (
    <div className="flex justify-between">
      <span className="text-gray-500">{k}{sub && <span className="text-[10px] text-gray-400 ml-1">{sub}</span>}</span>
      <span className={amber ? 'text-amber-600' : green ? 'text-leaf' : 'font-medium'}>{v}</span>
    </div>
  )
}
