import { useState, useEffect, useRef, type FormEvent } from 'react'
import { useNavigate, useParams, Link } from 'react-router-dom'
import { useQuery, useQueryClient, useMutation } from '@tanstack/react-query'
import { ArrowLeft, Trash2, Save, CheckCircle, Upload } from 'lucide-react'
import { api } from '@/lib/api'
import { Button } from '@/components/Button'
import { Field, TextArea, Select, NumberInput, Checkbox } from '@/components/Field'
import { DateField } from '@/components/DateField'
import { useStores } from '@/lib/useLookups'
import { InventoryStatus, type InventoryDto } from '@/lib/types'

interface LineRow {
  productId: string
  productName: string
  productArticle: string | null
  unitSymbol: string | null
  bookQty: number
  actualQty: number
  diff: number
  unitCost: number
}

interface Form {
  date: string
  storeId: string
  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: '', notes: '', lines: [] }

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

  const stores = useStores()
  const [form, setForm] = useState<Form>(emptyForm)
  const [error, setError] = useState<string | null>(null)
  const csvInputRef = useRef<HTMLInputElement>(null)

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

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

  useEffect(() => {
    if (isNew && !form.storeId && stores.data?.length) {
      const main = stores.data.find((s) => s.isMain) ?? stores.data[0]
      setForm((f) => ({ ...f, storeId: main.id }))
    }
  }, [isNew, stores.data, form.storeId])

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

  const surplusValue = form.lines.filter((l) => l.diff > 0).reduce((s, l) => s + l.diff * l.unitCost, 0)
  const shortageValue = form.lines.filter((l) => l.diff < 0).reduce((s, l) => s + l.diff * l.unitCost, 0)

  const create = useMutation({
    mutationFn: async () => {
      // Создание подгружает строки автоматически (lines: []) от текущего Stock склада.
      const payload = {
        date: new Date(form.date).toISOString(),
        storeId: form.storeId,
        notes: form.notes || null,
        lines: [],
      }
      return (await api.post<InventoryDto>('/api/inventory/inventories', payload)).data
    },
    onSuccess: (created) => {
      qc.invalidateQueries({ queryKey: ['/api/inventory/inventories'] })
      navigate(`/inventory/inventories/${created.id}`)
    },
    onError: (e: Error) => setError(e.message),
  })

  const save = useMutation({
    mutationFn: async () => {
      const payload = {
        date: new Date(form.date).toISOString(),
        storeId: form.storeId,
        notes: form.notes || null,
        lines: form.lines.map((l) => ({ productId: l.productId, actualQty: l.actualQty })),
      }
      await api.put(`/api/inventory/inventories/${id}`, payload)
      return null
    },
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['/api/inventory/inventories'] })
      existing.refetch()
    },
    onError: (e: Error) => setError(e.message),
  })

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

  const onSubmit = (e: FormEvent) => {
    e.preventDefault()
    if (isNew) create.mutate()
    else save.mutate()
  }

  const updateLine = (i: number, actualQty: number) => {
    setForm({
      ...form,
      lines: form.lines.map((l, ix) => ix === i
        ? { ...l, actualQty, diff: actualQty - l.bookQty }
        : l),
    })
  }

  /** Импорт CSV: ожидаемый формат «productId;actualQty» или «article;actualQty»
   * (article совпадение через productArticle). Заголовок не обязателен. */
  const onCsvUpload = async (file: File) => {
    const text = await file.text()
    const rows = text.split(/\r?\n/).map((r) => r.trim()).filter(Boolean)
    const byArticle = new Map<string, number>()
    for (const r of rows) {
      const [a, b] = r.split(';').map((s) => s.trim())
      if (!a || !b) continue
      if (a.toLowerCase() === 'productid' || a.toLowerCase() === 'article') continue
      const qty = Number(b.replace(',', '.'))
      if (!Number.isFinite(qty)) continue
      byArticle.set(a, qty)
    }
    setForm((f) => ({
      ...f,
      lines: f.lines.map((l) => {
        const fromId = byArticle.get(l.productId)
        const fromArticle = l.productArticle ? byArticle.get(l.productArticle) : undefined
        const v = fromId ?? fromArticle
        if (v == null) return l
        return { ...l, actualQty: v, diff: v - l.bookQty }
      }),
    }))
  }

  const canPost = isDraft && form.lines.some((l) => l.diff !== 0) && !isNew

  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/inventories" 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">
          {!isNew && isDraft && (
            <>
              <input ref={csvInputRef} type="file" accept=".csv,text/csv" className="hidden"
                onChange={(e) => { const f = e.target.files?.[0]; if (f) onCsvUpload(f) }} />
              <Button type="button" variant="secondary" size="sm" onClick={() => csvInputRef.current?.click()}>
                <Upload className="w-4 h-4" /> Импорт CSV
              </Button>
              <Button type="button" variant="danger" size="sm" onClick={() => { if (confirm('Удалить черновик?')) remove.mutate() }}>
                <Trash2 className="w-4 h-4" /> Удалить
              </Button>
            </>
          )}
          {isDraft && (
            <Button type="submit" disabled={!form.storeId || (create.isPending || save.isPending)}>
              <Save className="w-4 h-4" />{' '}
              {isNew
                ? (create.isPending ? 'Создаю…' : 'Создать и загрузить остатки')
                : (save.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">
          {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={!isNew}
                  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="Комментарий" className="md:col-span-3">
                <TextArea rows={2} value={form.notes} disabled={isPosted}
                  onChange={(e) => setForm({ ...form, notes: e.target.value })}
                  placeholder="Состав комиссии, ссылка на акт…" />
              </Field>
            </div>

            <div className="mt-4 flex flex-wrap gap-3 text-sm">
              <span className="px-2 py-1 rounded bg-green-50 text-green-700">Излишек: +{surplusValue.toLocaleString('ru')}</span>
              <span className="px-2 py-1 rounded bg-red-50 text-red-700">Недостача: {shortageValue.toLocaleString('ru')}</span>
              <span className="px-2 py-1 rounded bg-slate-50 text-slate-600">Итого расхождений: {(surplusValue + shortageValue).toLocaleString('ru')}</span>
            </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 || !canPost && !isPosted}
                  onChange={(v) => {
                    if (v) {
                      if (confirm('Провести? Учтённые остатки будут скорректированы на разницу.')) post.mutate()
                    } else {
                      if (confirm('Снять проведение? Корректировки отменятся.')) unpost.mutate()
                    }
                  }}
                />
              </div>
            )}
          </section>

          {!isNew && (
            <section className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-4">
              <h2 className="font-medium text-slate-900 dark:text-slate-100 mb-3">Позиции</h2>
              {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-[110px] text-right">Учёт</th>
                        <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[130px] text-right">Факт</th>
                        <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[110px] text-right">Расхожд.</th>
                        <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[110px] text-right">Цена ед.</th>
                        <th className="py-2 px-3 font-medium text-xs uppercase text-slate-500 w-[130px] text-right">Сумма</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.bookQty.toLocaleString('ru')}</td>
                          <td className="py-2 px-3 text-right">
                            <NumberInput value={l.actualQty} disabled={isPosted}
                              onChange={(v) => updateLine(i, v ?? 0)} />
                          </td>
                          <td className={`py-2 px-3 text-right font-mono ${l.diff > 0 ? 'text-green-700' : l.diff < 0 ? 'text-red-700' : 'text-slate-500'}`}>
                            {l.diff === 0 ? '—' : `${l.diff > 0 ? '+' : ''}${l.diff.toLocaleString('ru')}`}
                          </td>
                          <td className="py-2 px-3 text-right font-mono text-slate-500">{l.unitCost.toLocaleString('ru')}</td>
                          <td className={`py-2 px-3 text-right font-mono ${l.diff > 0 ? 'text-green-700' : l.diff < 0 ? 'text-red-700' : 'text-slate-500'}`}>
                            {l.diff === 0 ? '—' : (l.diff * l.unitCost).toLocaleString('ru')}
                          </td>
                        </tr>
                      ))}
                    </tbody>
                  </table>
                </div>
              )}
            </section>
          )}

          {isNew && (
            <section className="bg-white dark:bg-slate-900 rounded-lg border border-slate-200 dark:border-slate-800 p-4">
              <p className="text-sm text-slate-600 dark:text-slate-300">
                После создания документа автоматически подтянутся все товары со склада с
                их учётным количеством. Затем введёшь фактические значения (вручную или через
                импорт CSV), и при проведении остатки скорректируются на разницу.
              </p>
            </section>
          )}
        </div>
      </div>
    </form>
  )
}
