import { useState, useEffect, useRef, 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 } from 'lucide-react'
import { api } from '@/lib/api'
import { Button } from '@/components/Button'
import { Field, TextArea, Select, AsyncSelect, Checkbox, MoneyInput, NumberInput } from '@/components/Field'
import { DateField } from '@/components/DateField'
import { ProductPicker } from '@/components/ProductPicker'
import { SupplyLineQuickAdd, type AddedProduct } from '@/components/SupplyLineQuickAdd'
import { useStores, useCurrencies, usePriceTypes } from '@/lib/useLookups'
import { useOrgSettings } from '@/lib/useOrgSettings'
import { SupplyStatus, type SupplyDto, type Product } from '@/lib/types'

interface LineRow {
  id?: string
  productId: string
  productName: string
  productArticle: string | null
  productBarcode: string | null
  unitName: string | null
  quantity: number
  unitPrice: number
  // Розничная цена с карточки товара на момент загрузки документа
  // (read-only baseline). Используется как placeholder для ручного override.
  currentRetailPrice: number | null
  retailPriceManuallyOverridden: boolean
  retailPriceOverride: number | null
}

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

// Локальный YYYY-MM-DD (без UTC-сдвига): toISOString() в часовом поясе KZ
// (UTC+5) с 03:00 до 05:00 утра вернул бы вчерашнюю дату.
const todayIso = () => {
  const d = new Date()
  const y = d.getFullYear()
  const m = String(d.getMonth() + 1).padStart(2, '0')
  const dd = String(d.getDate()).padStart(2, '0')
  return `${y}-${m}-${dd}`
}

const emptyForm: Form = {
  date: todayIso(),
  supplierId: '', storeId: '', currencyId: '',
  notes: '',
  lines: [],
}

export function SupplyEditPage() {
  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 priceTypes = usePriceTypes()
  // Системный (главный) тип цен — на нём по умолчанию ведётся розница на кассе.
  // Заголовок колонки «Розничная» подменяется его именем чтобы соответствовать
  // тому, что увидит пользователь в карточке товара и в справочнике типов цен.
  const systemPriceTypeName = priceTypes.data?.find((pt) => pt.isSystem)?.name
    ?? priceTypes.data?.find((pt) => pt.isRetail)?.name
    ?? 'Розничная'

  const [form, setForm] = useState<Form>(emptyForm)
  const [pickerOpen, setPickerOpen] = useState(false)
  const [error, setError] = useState<string | null>(null)
  // Скролл-контейнер тела документа: после каждого добавления строки
  // автоскроллим к низу, чтобы новая строка и input оказались в зоне видимости.
  const scrollBodyRef = useRef<HTMLDivElement>(null)
  const scrollToBottom = () => {
    const el = scrollBodyRef.current
    if (!el) return
    requestAnimationFrame(() => {
      el.scrollTo({ top: el.scrollHeight, behavior: 'smooth' })
    })
  }

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

  useEffect(() => {
    if (!isNew && existing.data) {
      const s = existing.data
      setForm({
        date: s.date.slice(0, 10),
        supplierId: s.supplierId,
        storeId: s.storeId,
        currencyId: s.currencyId,
        notes: s.notes ?? '',
        lines: s.lines.map((l) => ({
          id: l.id ?? undefined,
          productId: l.productId,
          productName: l.productName ?? '',
          productArticle: l.productArticle,
          productBarcode: l.productBarcode,
          unitName: l.unitName,
          quantity: l.quantity,
          unitPrice: l.unitPrice,
          currentRetailPrice: l.currentRetailPrice ?? null,
          retailPriceManuallyOverridden: l.retailPriceManuallyOverridden ?? false,
          retailPriceOverride: l.retailPriceOverride ?? null,
        })),
      })
    }
  }, [isNew, existing.data])

  useEffect(() => {
    // Prefill defaults for new document.
    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 === SupplyStatus.Draft
  const isPosted = existing.data?.status === SupplyStatus.Posted

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

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

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

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

  const addLineFromProduct = (p: Product) => {
    const defaultRetail = p.prices?.[0]?.amount ?? null
    const primaryBarcode = (p.barcodes ?? []).slice().sort((a, b) => Number(b.isPrimary) - Number(a.isPrimary))[0]?.code ?? null
    setForm({
      ...form,
      lines: [...form.lines, {
        productId: p.id,
        productName: p.name,
        productArticle: p.article,
        productBarcode: primaryBarcode,
        unitName: p.unitName,
        quantity: 1,
        unitPrice: p.referencePrice ?? p.cost ?? 0,
        currentRetailPrice: defaultRetail,
        retailPriceManuallyOverridden: false,
        retailPriceOverride: null,
      }],
    })
  }

  /** Inline-добавление: если такой productId уже есть в строках — Quantity +1
   * (возвращаем true для UX-подсветки). Иначе создаём новую строку. */
  const addOrIncrementLine = (p: AddedProduct): boolean => {
    const idx = form.lines.findIndex((l) => l.productId === p.id)
    if (idx >= 0) {
      setForm({
        ...form,
        lines: form.lines.map((l, ix) => ix === idx ? { ...l, quantity: l.quantity + 1 } : l),
      })
      scrollToBottom()
      return true
    }
    const defaultRetail = p.prices?.[0]?.amount ?? null
    setForm({
      ...form,
      lines: [...form.lines, {
        productId: p.id,
        productName: p.name,
        productArticle: p.article,
        productBarcode: p.barcode,
        unitName: p.unitName,
        quantity: 1,
        unitPrice: p.referencePrice ?? p.cost ?? 0,
        currentRetailPrice: defaultRetail,
        retailPriceManuallyOverridden: false,
        retailPriceOverride: null,
      }],
    })
    scrollToBottom()
    return false
  }
  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.supplierId && !!form.storeId && !!form.currencyId
    && form.lines.length > 0
    && isDraft

  return (
    <form onSubmit={onSubmit} className="flex flex-col h-full">
      {/* Sticky top bar */}
      <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="/purchases/supplies" 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>

      {/* Scrollable body */}
      <div ref={scrollBodyRef} 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="Дата *">
                <DateField required value={form.date || null} disabled={isPosted}
                  onChange={(iso) => setForm({ ...form, date: iso ?? '' })} />
              </Field>
              <Field label="Поставщик *">
                <AsyncSelect
                  url="/api/catalog/counterparties"
                  value={form.supplierId}
                  disabled={isPosted}
                  onChange={(v) => setForm({ ...form, supplierId: v })}
                  placeholder="Выберите поставщика…"
                  createLabel="Создать поставщика"
                  onCreate={async (name) => {
                    const created = await api.post<{ id: string }>('/api/catalog/counterparties', {
                      name, legalName: null, type: 1,
                      bin: null, iin: null, taxNumber: null, countryId: null,
                      address: null, phone: null, email: null,
                      bankName: null, bankAccount: null, bik: null, contactPerson: null, notes: null,
                    })
                    return created.data.id
                  }}
                />
              </Field>
              {(stores.data?.length ?? 0) > 1 && (
                <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="Примечание" className="md:col-span-3">
                <TextArea rows={2} value={form.notes} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, notes: e.target.value })} />
              </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
                    || form.lines.some(l => l.quantity <= 0 || l.unitPrice <= 0)}
                  onChange={(v) => {
                    if (v) {
                      if (confirm('После проведения товары будут оприходованы на склад и обновят себестоимость (скользящее среднее). Продолжить?')) post.mutate()
                    } else {
                      if (confirm('Снять проведение? Остатки откатятся, себестоимость останется (пересчитать вручную при необходимости).')) unpost.mutate()
                    }
                  }}
                />
                <p className="text-xs text-slate-500 mt-1">
                  Только проведённый документ влияет на остатки склада и себестоимость.
                  Черновик можно править, проведённый — только распровести и редактировать заново.
                  {isPosted && existing.data?.postedAt && (
                    <> Проведён {new Date(existing.data.postedAt).toLocaleString('ru')}.</>
                  )}
                </p>
              </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-red-600 py-3 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 tracking-wide text-slate-500">Товар</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[90px]">Ед.</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 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[140px] text-right">Цена</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[160px] text-right">{systemPriceTypeName} (карточка)</th>
                      <th className="py-2 px-3 font-medium text-xs uppercase tracking-wide text-slate-500 w-[160px] 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 || l.productBarcode) && (
                            <div className="text-xs text-slate-400 font-mono">
                              {l.productArticle && <span>Арт: {l.productArticle}</span>}
                              {l.productArticle && l.productBarcode && <span className="mx-1.5">·</span>}
                              {l.productBarcode && <span>ШК: {l.productBarcode}</span>}
                            </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.retailPriceManuallyOverridden ? l.retailPriceOverride : l.currentRetailPrice}
                            onChange={(n) => updateLine(i, {
                              retailPriceManuallyOverridden: true,
                              retailPriceOverride: n,
                            })}
                            currencyCode={currencies.data?.find((c) => c.id === form.currencyId)?.code}
                            currencySymbol={currencies.data?.find((c) => c.id === form.currencyId)?.symbol}
                            placeholder={l.currentRetailPrice != null ? String(l.currentRetailPrice) : '—'}
                          />
                        </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={5} className="py-3 pr-3 text-right text-sm font-semibold text-slate-600 dark:text-slate-300">
                        Итого:
                      </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>

      {/* Quick-add bar — flex-sibling формы, всегда у нижнего края viewport.
        * Не sticky внутри scroll-body, чтобы overflow родителей и высота
        * содержимого не влияли на видимость. После каждого добавления
        * строки тело документа автоскроллится к низу. */}
      {!isPosted && (
        <div className="flex-shrink-0 bg-white dark:bg-slate-900 border-t border-slate-200 dark:border-slate-800 px-3 sm:px-6 py-3 shadow-[0_-4px_12px_rgba(0,0,0,0.04)]">
          <div className="max-w-6xl mx-auto">
            <SupplyLineQuickAdd
              storeId={form.storeId}
              onPick={addOrIncrementLine}
              linesCount={form.lines.length}
            />
          </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>
  )
}
