import { useState, useEffect, type FormEvent } from 'react'
import { useNavigate, useParams, Link } from 'react-router-dom'
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query'
import { ArrowLeft, Plus, Trash2, Save, CheckCircle } from 'lucide-react'
import { api } from '@/lib/api'
import { Button } from '@/components/Button'
import { Field, TextArea, Select, MoneyInput, NumberInput, Checkbox } from '@/components/Field'
import { DateField } from '@/components/DateField'
import { ProductPicker } from '@/components/ProductPicker'
import { useStores, useCurrencies } from '@/lib/useLookups'
import { useOrgSettings } from '@/lib/useOrgSettings'
import { LossStatus, LossReason, lossReasonLabel, type LossDto, type Product } from '@/lib/types'

interface LineRow {
  productId: string
  productName: string
  productArticle: string | null
  unitSymbol: string | null
  quantity: number
  unitCost: number
  stockAtStore: number | null
}

interface Form {
  date: string
  storeId: string
  currencyId: string
  reason: LossReason
  notes: string
  lines: LineRow[]
}

const todayIso = () => {
  const d = new Date()
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

const emptyForm: Form = {
  date: todayIso(), storeId: '', currencyId: '', reason: LossReason.Other, notes: '', lines: [],
}

export function LossEditPage() {
  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>(emptyForm)
  const [pickerOpen, setPickerOpen] = useState(false)
  const [error, setError] = useState<string | null>(null)

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

  useEffect(() => {
    if (!isNew && existing.data) {
      const s = existing.data
      setForm({
        date: s.date.slice(0, 10),
        storeId: s.storeId,
        currencyId: s.currencyId,
        reason: s.reason,
        notes: s.notes ?? '',
        lines: s.lines.map((l) => ({
          productId: l.productId,
          productName: l.productName ?? '',
          productArticle: l.productArticle,
          unitSymbol: l.unitSymbol,
          quantity: l.quantity,
          unitCost: l.unitCost,
          stockAtStore: l.stockAtStore,
        })),
      })
    }
  }, [isNew, existing.data])

  useEffect(() => {
    if (isNew) {
      if (!form.storeId && stores.data?.length) {
        const main = stores.data.find((s) => s.isMain) ?? stores.data[0]
        setForm((f) => ({ ...f, storeId: main.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 === LossStatus.Draft
  const isPosted = existing.data?.status === LossStatus.Posted

  const lineTotal = (l: LineRow) => l.quantity * l.unitCost
  const grandTotal = form.lines.reduce((s, l) => s + lineTotal(l), 0)

  const save = useMutation({
    mutationFn: async () => {
      const payload = {
        date: new Date(form.date).toISOString(),
        storeId: form.storeId,
        currencyId: form.currencyId,
        reason: form.reason,
        notes: form.notes || null,
        lines: form.lines.map((l) => ({
          productId: l.productId, quantity: l.quantity, unitCost: l.unitCost,
        })),
      }
      if (isNew) return (await api.post<LossDto>('/api/inventory/losses', payload)).data
      await api.put(`/api/inventory/losses/${id}`, payload)
      return null
    },
    onSuccess: (created) => {
      qc.invalidateQueries({ queryKey: ['/api/inventory/losses'] })
      navigate(created ? `/inventory/losses/${created.id}` : `/inventory/losses/${id}`)
    },
    onError: (e: Error) => setError(e.message),
  })

  const post = useMutation({
    mutationFn: async () => { await api.post(`/api/inventory/losses/${id}/post`) },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['/api/inventory/losses'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/stock'] })
      qc.invalidateQueries({ queryKey: ['/api/inventory/movements'] })
      existing.refetch()
    },
    onError: (e: Error) => {
      const msg = (e as { response?: { data?: { error?: string } } }).response?.data?.error ?? e.message
      setError(msg)
    },
  })

  const unpost = useMutation({
    mutationFn: async () => { await api.post(`/api/inventory/losses/${id}/unpost`) },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['/api/inventory/losses'] })
      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/inventory/losses/${id}`) },
    onSuccess: () => navigate('/inventory/losses'),
    onError: (e: Error) => setError(e.message),
  })

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

  const addLineFromProduct = (p: Product) => {
    setForm({
      ...form,
      lines: [...form.lines, {
        productId: p.id,
        productName: p.name,
        productArticle: p.article,
        unitSymbol: p.unitName,
        quantity: 1,
        unitCost: p.cost ?? 0,
        stockAtStore: null,
      }],
    })
  }
  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.date && !!form.storeId && !!form.currencyId
    && form.lines.length > 0 && isDraft

  const fractional = org.data?.allowFractionalPrices ?? false
  const moneyFmt = fractional
    ? { minimumFractionDigits: 2, maximumFractionDigits: 2 }
    : { maximumFractionDigits: 0 }

  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="/inventory/losses" 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-3 flex-shrink-0 items-center">
          {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" disabled={!canSave || save.isPending}>
              <Save className="w-4 h-4" /> {save.isPending ? 'Сохраняю…' : 'Сохранить'}
            </Button>
          )}
        </div>
      </div>

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

          <section className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-4">
            <div className="grid grid-cols-1 md:grid-cols-3 gap-x-4 gap-y-3">
              <Field label="Дата *">
                <DateField required value={form.date || null} disabled={isPosted}
                  onChange={(iso) => setForm({ ...form, date: iso ?? '' })} />
              </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>
              <Field label="Причина *">
                <Select value={String(form.reason)} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, reason: Number(e.target.value) as LossReason })}>
                  {Object.entries(lossReasonLabel).map(([v, lbl]) => (
                    <option key={v} value={v}>{lbl}</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="Комментарий" className="md:col-span-3">
                <TextArea rows={2} value={form.notes} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, notes: e.target.value })}
                  placeholder="Детали (партия, накладная, акт)…" />
              </Field>
            </div>

            {!isNew && (
              <div className="mt-4 pt-4 border-t border-slate-100 dark:border-slate-800">
                <Checkbox
                  label="Проведено"
                  checked={isPosted}
                  disabled={post.isPending || unpost.isPending || form.lines.length === 0}
                  onChange={(v) => {
                    if (v) {
                      if (confirm('Провести? Товар будет списан со склада.')) post.mutate()
                    } else {
                      if (confirm('Снять проведение? Списанный товар вернётся на остаток.')) unpost.mutate()
                    }
                  }}
                />
              </div>
            )}
          </section>

          <section className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-4">
            <div className="flex items-center justify-between mb-3">
              <h2 className="font-medium text-slate-900 dark:text-slate-100">Позиции</h2>
              {!isPosted && (
                <Button type="button" variant="secondary" size="sm" onClick={() => setPickerOpen(true)}>
                  <Plus className="w-3.5 h-3.5" /> Добавить из справочника
                </Button>
              )}
            </div>

            {form.lines.length === 0 ? (
              <div className="text-sm text-slate-500 py-6 text-center">Нет позиций.</div>
            ) : (
              <div className="overflow-x-auto">
                <table className="w-full text-sm">
                  <thead className="text-left">
                    <tr className="border-b border-slate-200 dark:border-slate-700">
                      <th className="py-2 pr-3 font-medium text-xs uppercase text-slate-500">Товар</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[80px]">Ед.</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[100px] text-right">Остаток</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[120px] text-right">Списать</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[140px] text-right">Цена ед.</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[140px] text-right">Сумма</th>
                      <th className="w-8"></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 text-slate-800 dark:text-slate-100">{l.productName || '(без названия)'}</div>
                          {l.productArticle && <div className="text-xs text-slate-500">{l.productArticle}</div>}
                        </td>
                        <td className="py-2 px-3 text-slate-500">{l.unitSymbol ?? '—'}</td>
                        <td className="py-2 px-3 text-right font-mono text-slate-500">
                          {l.stockAtStore != null ? l.stockAtStore.toLocaleString('ru') : '—'}
                        </td>
                        <td className="py-2 px-3 text-right">
                          <NumberInput value={l.quantity} disabled={isPosted}
                            onChange={(v) => updateLine(i, { quantity: v ?? 0 })} />
                        </td>
                        <td className="py-2 px-3 text-right">
                          <MoneyInput value={l.unitCost} disabled={isPosted}
                            allowFractional={fractional}
                            onChange={(v) => updateLine(i, { unitCost: v ?? 0 })} />
                        </td>
                        <td className="py-2 px-3 text-right font-mono">
                          {lineTotal(l).toLocaleString('ru', moneyFmt)}
                        </td>
                        <td className="py-2 px-1">
                          {!isPosted && (
                            <button type="button" onClick={() => removeLine(i)}
                              className="text-slate-400 hover:text-red-600">
                              <Trash2 className="w-4 h-4" />
                            </button>
                          )}
                        </td>
                      </tr>
                    ))}
                    <tr className="font-medium">
                      <td className="py-3 pr-3" colSpan={5}>Итого</td>
                      <td className="py-3 px-3 text-right font-mono">
                        {grandTotal.toLocaleString('ru', moneyFmt)} {existing.data?.currencyCode ?? ''}
                      </td>
                      <td />
                    </tr>
                  </tbody>
                </table>
              </div>
            )}
          </section>
        </div>
      </div>

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