import { useState, useEffect, type FormEvent, type ReactNode } from 'react'
import { useNavigate, useParams, Link } from 'react-router-dom'
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query'
import { ArrowLeft, Plus, Trash2, Save, CheckCircle, Undo2 } from 'lucide-react'
import { api } from '@/lib/api'
import { Button } from '@/components/Button'
import { Field, TextInput, TextArea, Select, AsyncSelect, MoneyInput, NumberInput } from '@/components/Field'
import { ProductPicker } from '@/components/ProductPicker'
import { useStores, useCurrencies } from '@/lib/useLookups'
import { useOrgSettings } from '@/lib/useOrgSettings'
import { RetailSaleStatus, PaymentMethod, type RetailSaleDto, type Product } from '@/lib/types'

interface LineRow {
  id?: string
  productId: string
  productName: string
  productArticle: string | null
  unitName: string | null
  quantity: number
  unitPrice: number
  discount: number
  vatPercent: number
}

interface Form {
  date: string
  storeId: string
  retailPointId: string
  customerId: string
  currencyId: string
  payment: PaymentMethod
  paidCash: number
  paidCard: number
  notes: string
  lines: LineRow[]
}

const todayIso = () => new Date().toISOString().slice(0, 16)

const empty: Form = {
  date: todayIso(),
  storeId: '', retailPointId: '', customerId: '', currencyId: '',
  payment: PaymentMethod.Cash, paidCash: 0, paidCard: 0,
  notes: '', lines: [],
}

export function RetailSaleEditPage() {
  const { id } = useParams<{ id: string }>()
  const isNew = !id || id === 'new'
  const navigate = useNavigate()
  const qc = useQueryClient()

  const stores = useStores()
  const currencies = useCurrencies()
  const org = useOrgSettings()

  const [form, setForm] = useState<Form>(empty)
  const [pickerOpen, setPickerOpen] = useState(false)
  const [error, setError] = useState<string | null>(null)

  const existing = useQuery({
    queryKey: ['/api/sales/retail', id],
    queryFn: async () => (await api.get<RetailSaleDto>(`/api/sales/retail/${id}`)).data,
    enabled: !isNew,
  })

  useEffect(() => {
    if (!isNew && existing.data) {
      const s = existing.data
      setForm({
        date: s.date.slice(0, 16),
        storeId: s.storeId,
        retailPointId: s.retailPointId ?? '',
        customerId: s.customerId ?? '',
        currencyId: s.currencyId,
        payment: s.payment,
        paidCash: s.paidCash,
        paidCard: s.paidCard,
        notes: s.notes ?? '',
        lines: s.lines.map((l) => ({
          id: l.id ?? undefined,
          productId: l.productId,
          productName: l.productName ?? '',
          productArticle: l.productArticle,
          unitName: l.unitName,
          quantity: l.quantity, unitPrice: l.unitPrice, discount: l.discount,
          vatPercent: l.vatPercent,
        })),
      })
    }
  }, [isNew, existing.data])

  useEffect(() => {
    if (isNew) {
      if (!form.storeId && stores.data?.length) {
        setForm((f) => ({ ...f, storeId: stores.data!.find((s) => s.isMain)?.id ?? stores.data![0].id }))
      }
      if (!form.currencyId && currencies.data?.length) {
        const def = org.data?.defaultCurrencyId
          ? currencies.data.find((c) => c.id === org.data!.defaultCurrencyId)
          : currencies.data.find((c) => c.code === 'KZT')
        if (def) setForm((f) => ({ ...f, currencyId: def.id }))
      }
    }
  }, [isNew, stores.data, currencies.data, org.data?.defaultCurrencyId, form.storeId, form.currencyId])

  const isDraft = isNew || existing.data?.status === RetailSaleStatus.Draft
  const isPosted = existing.data?.status === RetailSaleStatus.Posted

  const lineTotal = (l: LineRow) => l.quantity * l.unitPrice - l.discount
  const subtotal = form.lines.reduce((s, l) => s + l.quantity * l.unitPrice, 0)
  const discountTotal = form.lines.reduce((s, l) => s + l.discount, 0)
  const grandTotal = subtotal - discountTotal

  const save = useMutation({
    mutationFn: async () => {
      const payload = {
        date: new Date(form.date).toISOString(),
        storeId: form.storeId,
        retailPointId: form.retailPointId || null,
        customerId: form.customerId || null,
        currencyId: form.currencyId,
        payment: form.payment,
        paidCash: Number(form.paidCash),
        paidCard: Number(form.paidCard),
        notes: form.notes || null,
        lines: form.lines.map((l) => ({
          productId: l.productId,
          quantity: l.quantity,
          unitPrice: l.unitPrice,
          discount: l.discount,
          vatPercent: l.vatPercent,
        })),
      }
      if (isNew) {
        return (await api.post<RetailSaleDto>('/api/sales/retail', payload)).data
      }
      await api.put(`/api/sales/retail/${id}`, payload)
      return null
    },
    onSuccess: (created) => {
      qc.invalidateQueries({ queryKey: ['/api/sales/retail'] })
      navigate(created ? `/sales/retail/${created.id}` : `/sales/retail/${id}`)
    },
    onError: (e: Error) => setError(e.message),
  })

  const post = useMutation({
    mutationFn: async () => { await api.post(`/api/sales/retail/${id}/post`) },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['/api/sales/retail'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/stock'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/movements'] })
      existing.refetch()
    },
    onError: (e: Error) => setError(e.message),
  })

  const unpost = useMutation({
    mutationFn: async () => { await api.post(`/api/sales/retail/${id}/unpost`) },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['/api/sales/retail'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/stock'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/movements'] })
      existing.refetch()
    },
    onError: (e: Error) => setError(e.message),
  })

  const remove = useMutation({
    mutationFn: async () => { await api.delete(`/api/sales/retail/${id}`) },
    onSuccess: () => navigate('/sales/retail'),
    onError: (e: Error) => setError(e.message),
  })

  const onSubmit = (e: FormEvent) => { e.preventDefault(); save.mutate() }

  const addLineFromProduct = (p: Product) => {
    const retail = p.prices.find((x) => x.priceTypeName?.toLowerCase().includes('розн')) ?? p.prices[0]
    setForm({
      ...form,
      lines: [...form.lines, {
        productId: p.id,
        productName: p.name,
        productArticle: p.article,
        unitName: p.unitName,
        quantity: 1,
        unitPrice: retail?.amount ?? 0,
        discount: 0,
        vatPercent: p.vat * 1,
      }],
    })
  }
  const updateLine = (i: number, patch: Partial<LineRow>) =>
    setForm({ ...form, lines: form.lines.map((l, ix) => ix === i ? { ...l, ...patch } : l) })
  const removeLine = (i: number) =>
    setForm({ ...form, lines: form.lines.filter((_, ix) => ix !== i) })

  const canSave = !!form.storeId && !!form.currencyId && isDraft

  return (
    <form onSubmit={onSubmit} className="flex flex-col h-full">
      <div className="flex items-center justify-between gap-4 px-6 py-3 border-b border-slate-200 dark:border-slate-800 bg-white dark:bg-slate-900">
        <div className="flex items-center gap-3 min-w-0">
          <Link to="/sales/retail" className="text-slate-400 hover:text-slate-700 dark:hover:text-slate-200 flex-shrink-0">
            <ArrowLeft className="w-5 h-5" />
          </Link>
          <div className="min-w-0">
            <h1 className="text-base font-semibold text-slate-900 dark:text-slate-100 truncate">
              {isNew ? 'Новый чек' : existing.data?.number ?? 'Чек'}
            </h1>
            <p className="text-xs text-slate-500">
              {isPosted
                ? <span className="text-green-700 inline-flex items-center gap-1"><CheckCircle className="w-3 h-3" /> Проведён {existing.data?.postedAt ? new Date(existing.data.postedAt).toLocaleString('ru') : ''}</span>
                : 'Черновик — товар не списывается со склада до проведения'}
            </p>
          </div>
        </div>
        <div className="flex gap-2 flex-shrink-0">
          {isPosted && (
            <Button type="button" variant="secondary" onClick={() => unpost.mutate()} disabled={unpost.isPending}>
              <Undo2 className="w-4 h-4" /> Отменить
            </Button>
          )}
          {isDraft && !isNew && (
            <Button type="button" variant="danger" size="sm" onClick={() => { if (confirm('Удалить черновик?')) remove.mutate() }}>
              <Trash2 className="w-4 h-4" /> Удалить
            </Button>
          )}
          {isDraft && (
            <Button type="submit" variant="secondary" disabled={!canSave || save.isPending}>
              <Save className="w-4 h-4" /> {save.isPending ? 'Сохраняю…' : 'Сохранить'}
            </Button>
          )}
          {isDraft && !isNew && (
            <Button type="button" onClick={() => post.mutate()} disabled={post.isPending || form.lines.length === 0}>
              <CheckCircle className="w-4 h-4" /> {post.isPending ? 'Провожу…' : 'Провести'}
            </Button>
          )}
        </div>
      </div>

      <div className="flex-1 overflow-auto">
        <div className="max-w-6xl mx-auto p-3 sm:p-6 space-y-4 sm:space-y-5">
          {error && <div className="p-3 rounded-md bg-red-50 text-red-700 text-sm border border-red-200">{error}</div>}

          <Section title="Реквизиты чека">
            <div className="grid grid-cols-1 md:grid-cols-3 gap-x-4 gap-y-3">
              <Field label="Дата/время">
                <TextInput type="datetime-local" value={form.date} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, date: e.target.value })} />
              </Field>
              <Field label="Магазин *">
                <Select value={form.storeId} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, storeId: e.target.value })}>
                  <option value="">—</option>
                  {stores.data?.map((s) => <option key={s.id} value={s.id}>{s.name}</option>)}
                </Select>
              </Field>
              {org.data?.multiCurrencyEnabled && (
                <Field label="Валюта *">
                  <Select value={form.currencyId} disabled={isPosted}
                    onChange={(e) => setForm({ ...form, currencyId: e.target.value })}>
                    <option value="">—</option>
                    {currencies.data?.map((c) => <option key={c.id} value={c.id}>{c.code}</option>)}
                  </Select>
                </Field>
              )}
              <Field label="Покупатель (опц.)">
                <AsyncSelect
                  url="/api/catalog/counterparties"
                  value={form.customerId}
                  disabled={isPosted}
                  onChange={(v) => setForm({ ...form, customerId: v })}
                  placeholder="— анонимный —"
                />
              </Field>
              <Field label="Способ оплаты">
                <Select value={form.payment} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, payment: Number(e.target.value) as PaymentMethod })}>
                  <option value={PaymentMethod.Cash}>Наличные</option>
                  <option value={PaymentMethod.Card}>Карта</option>
                  <option value={PaymentMethod.BankTransfer}>Банковский перевод</option>
                  <option value={PaymentMethod.Bonus}>Бонусы</option>
                  <option value={PaymentMethod.Mixed}>Смешанная</option>
                </Select>
              </Field>
              <Field label="Получено наличными">
                <MoneyInput value={form.paidCash} disabled={isPosted}
                  onChange={(n) => setForm({ ...form, paidCash: n ?? 0 })}
                  currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code}
                  currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol}
 />
              </Field>
              <Field label="Получено картой">
                <MoneyInput value={form.paidCard} disabled={isPosted}
                  onChange={(n) => setForm({ ...form, paidCard: n ?? 0 })}
                  currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code}
                  currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol}
 />
              </Field>
              <Field label="Примечание" className="md:col-span-3">
                <TextArea rows={2} value={form.notes} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, notes: e.target.value })} />
              </Field>
            </div>
          </Section>

          <Section
            title="Позиции"
            action={!isPosted && (
              <Button type="button" variant="secondary" size="sm" onClick={() => setPickerOpen(true)}>
                <Plus className="w-3.5 h-3.5" /> Добавить товар
              </Button>
            )}
          >
            {form.lines.length === 0 ? (
              <div className="text-sm text-slate-400 py-4 text-center">Пусто. Добавь хотя бы одну позицию.</div>
            ) : (
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead>
                    <tr className="border-b border-slate-200 dark:border-slate-700 text-left">
                      <th className="py-2 pr-3 font-medium text-xs uppercase tracking-wide text-slate-500">Товар</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[80px]">Ед.</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[120px] text-right">Кол-во</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[120px] text-right">Цена</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[110px] text-right">Скидка</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[140px] text-right">Сумма</th>
                      <th className="py-2 pl-3 w-[40px]"></th>
                    </tr>
                  </thead>
                  <tbody>
                    {form.lines.map((l, i) => (
                      <tr key={i} className="border-b border-slate-100 dark:border-slate-800">
                        <td className="py-2 pr-3">
                          <div className="font-medium">{l.productName}</div>
                          {l.productArticle && <div className="text-xs text-slate-400 font-mono">{l.productArticle}</div>}
                        </td>
                        <td className="py-2 px-3 text-slate-500">{l.unitName}</td>
                        <td className="py-2 px-3">
                          <NumberInput disabled={isPosted}
                            value={l.quantity}
                            onChange={(n) => updateLine(i, { quantity: n ?? 0 })} />
                        </td>
                        <td className="py-2 px-3">
                          <MoneyInput disabled={isPosted}
                            value={l.unitPrice}
                            onChange={(n) => updateLine(i, { unitPrice: n ?? 0 })}
                            currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code}
                            currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol}
 />
                        </td>
                        <td className="py-2 px-3">
                          <MoneyInput disabled={isPosted}
                            value={l.discount}
                            onChange={(n) => updateLine(i, { discount: n ?? 0 })}
                            currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code}
                            currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol}
 />
                        </td>
                        <td className="py-2 px-3 text-right font-mono font-semibold">
                          {lineTotal(l).toLocaleString('ru', { maximumFractionDigits: 2 })}
                        </td>
                        <td className="py-2 pl-3">
                          {!isPosted && (
                            <button type="button" onClick={() => removeLine(i)} className="text-slate-400 hover:text-red-600">
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                        </td>
                      </tr>
                    ))}
                  </tbody>
                  <tfoot>
                    <tr><td colSpan={4} className="py-2 pr-3 text-right text-sm text-slate-500">Подытог:</td>
                      <td className="py-2 px-3 text-right text-sm text-slate-500"></td>
                      <td className="py-2 px-3 text-right font-mono">{subtotal.toLocaleString('ru', { maximumFractionDigits: 2 })}</td>
                      <td/></tr>
                    <tr><td colSpan={4} className="py-1 pr-3 text-right text-sm text-slate-500">Скидка:</td>
                      <td className="py-1 px-3"></td>
                      <td className="py-1 px-3 text-right font-mono text-red-600">−{discountTotal.toLocaleString('ru', { maximumFractionDigits: 2 })}</td>
                      <td/></tr>
                    <tr><td colSpan={4} className="py-3 pr-3 text-right text-sm font-semibold text-slate-700 dark:text-slate-200">К оплате:</td>
                      <td/>
                      <td className="py-3 px-3 text-right font-mono text-lg font-bold">
                        {grandTotal.toLocaleString('ru', { maximumFractionDigits: 2 })}{' '}
                        <span className="text-sm text-slate-500">{currencies.data?.find((c) => c.id === form.currencyId)?.code ?? ''}</span>
                      </td><td/></tr>
                  </tfoot>
                </table>
              </div>
            )}
          </Section>
        </div>
      </div>

      <ProductPicker open={pickerOpen} onClose={() => setPickerOpen(false)} onPick={addLineFromProduct} />
    </form>
  )
}

function Section({ title, children, action }: { title: string; children: ReactNode; action?: ReactNode }) {
  return (
    <section className="bg-white dark:bg-slate-900 rounded-xl border border-slate-200 dark:border-slate-800 overflow-hidden">
      <header className="flex items-center justify-between px-5 py-3 border-b border-slate-100 dark:border-slate-800 bg-slate-50/50 dark:bg-slate-800/30">
        <h2 className="text-sm font-semibold text-slate-900 dark:text-slate-100">{title}</h2>
        {action}
      </header>
      <div className="p-5">{children}</div>
    </section>
  )
}
