import { useState } from 'react'
import { Link, useNavigate } from 'react-router-dom'
import { DataTable } from '@/components/DataTable'
import { Pagination } from '@/components/Pagination'
import { SearchBar } from '@/components/SearchBar'
import { Button } from '@/components/Button'
import { Plus, Filter, X, FolderTree } from 'lucide-react'
import { useCatalogList } from '@/lib/useCatalog'
import { useOrgSettings } from '@/lib/useOrgSettings'
import { usePriceTypes } from '@/lib/useLookups'
import { ProductGroupTree } from '@/components/ProductGroupTree'
import { MoneyInput } from '@/components/Field'
import { packagingLabel, type Product } from '@/lib/types'

const URL = '/api/catalog/products'

type TriFilter = 'all' | 'yes' | 'no'

interface Filters {
  groupId: string | null
  isService: TriFilter
  packaging: number | null   // null = все, 1/2/3 = Piece/Weight/Liquid
  isMarked: TriFilter
  systemPriceFrom: number | null
  systemPriceTo: number | null
}

const defaultFilters: Filters = {
  groupId: null,
  isService: 'all',
  packaging: null,
  isMarked: 'all',
  systemPriceFrom: null,
  systemPriceTo: null,
}

const toExtra = (f: Filters): Record<string, string | number | boolean | undefined> => {
  const e: Record<string, string | number | boolean | undefined> = {}
  if (f.groupId) e.groupId = f.groupId
  if (f.isService !== 'all') e.isService = f.isService === 'yes'
  if (f.packaging) e.packaging = f.packaging
  if (f.isMarked !== 'all') e.isMarked = f.isMarked === 'yes'
  if (f.systemPriceFrom != null) e.systemPriceFrom = f.systemPriceFrom
  if (f.systemPriceTo != null) e.systemPriceTo = f.systemPriceTo
  return e
}

const activeFilterCount = (f: Filters) => {
  let n = 0
  if (f.groupId) n++
  if (f.isService !== 'all') n++
  if (f.packaging) n++
  if (f.isMarked !== 'all') n++
  if (f.systemPriceFrom != null) n++
  if (f.systemPriceTo != null) n++
  return n
}

function Tri({
  label, value, onChange, yesLabel = 'да', noLabel = 'нет',
}: {
  label: string
  value: TriFilter
  onChange: (v: TriFilter) => void
  yesLabel?: string
  noLabel?: string
}) {
  const opts: { v: TriFilter; t: string }[] = [
    { v: 'all', t: 'все' },
    { v: 'yes', t: yesLabel },
    { v: 'no', t: noLabel },
  ]
  return (
    <div className="flex items-center gap-2 text-xs">
      <span className="text-slate-500">{label}</span>
      <div className="inline-flex rounded border border-slate-200 dark:border-slate-700 overflow-hidden">
        {opts.map((o) => (
          <button
            key={o.v}
            type="button"
            onClick={() => onChange(o.v)}
            className={
              'px-2 py-0.5 ' +
              (value === o.v
                ? 'bg-slate-900 text-white dark:bg-slate-200 dark:text-slate-900'
                : 'bg-white dark:bg-slate-900 text-slate-600 hover:bg-slate-50 dark:hover:bg-slate-800')
            }
          >
            {o.t}
          </button>
        ))}
      </div>
    </div>
  )
}

export function ProductsPage() {
  const navigate = useNavigate()
  const [filters, setFilters] = useState<Filters>(defaultFilters)
  const [filtersOpen, setFiltersOpen] = useState(false)
  const { data, isLoading, page, setPage, search, setSearch, sortKey, sortOrder, setSort } = useCatalogList<Product>(URL, toExtra(filters))
  const org = useOrgSettings()
  const priceTypes = usePriceTypes()
  const systemPriceType = priceTypes.data?.find((pt) => pt.isSystem) ?? priceTypes.data?.find((pt) => pt.isRetail) ?? priceTypes.data?.[0]
  const showVat = org.data?.showVatEnabledOnProduct ?? false
  const showService = org.data?.showServiceOnProduct ?? false
  const showMarked = org.data?.showMarkedOnProduct ?? false
  const activeCount = activeFilterCount(filters)
  const [groupsOpen, setGroupsOpen] = useState(false)

  type Col = {
    header: string
    width?: string
    className?: string
    sortKey?: string
    cell: (r: Product) => React.ReactNode
  }
  const baseColumns: Col[] = [
    { header: 'Название', sortKey: 'name', cell: (r) => (
      <div>
        <div className="font-medium">{r.name}</div>
        {r.article && <div className="text-xs text-slate-400 font-mono">{r.article}</div>}
      </div>
    )},
    { header: 'Фасовка', width: '110px', sortKey: 'packaging', cell: (r) => packagingLabel[r.packaging] ?? '—' },
    { header: 'Штрихкод', width: '160px', cell: (r) => (
      <span className="font-mono">{r.barcodes[0]?.code ?? '—'}</span>
    )},
    // Себестоимость — расчётное скользящее среднее. До первой проведённой
    // приёмки = 0; в этом случае показываем «—», чтобы визуально отличать
    // «не накопилась» от «реально стоит 0».
    {
      header: 'Себестоимость',
      width: '160px',
      className: 'text-right font-mono',
      sortKey: 'cost',
      cell: (r) => {
        if (r.cost == null || r.cost === 0) return '—'
        const fractional = org.data?.allowFractionalPrices ?? false
        const num = r.cost.toLocaleString('ru',
          fractional
            ? { minimumFractionDigits: 2, maximumFractionDigits: 2 }
            : { maximumFractionDigits: 0 })
        return `${num} ${org.data?.defaultCurrencySymbol ?? org.data?.defaultCurrencyCode ?? ''}`.trim()
      },
    },
    // Колонка системной розничной цены: заголовок = PriceType.Name той записи
    // что помечена IsSystem (если пользователь её переименовал — заголовок меняется).
    {
      header: systemPriceType?.name ?? 'Розничная цена',
      width: '170px',
      className: 'text-right font-mono',
      sortKey: 'systemPrice',
      cell: (r) => {
        const pr = systemPriceType ? r.prices?.find(x => x.priceTypeId === systemPriceType.id) : undefined
        if (!pr) return '—'
        const fractional = org.data?.allowFractionalPrices ?? false
        const num = pr.amount.toLocaleString('ru',
          fractional
            ? { minimumFractionDigits: 2, maximumFractionDigits: 2 }
            : { maximumFractionDigits: 0 })
        return `${num} ${pr.currencyCode ?? ''}`.trim()
      },
    },
  ]
  if (showVat) {
    baseColumns.push({ header: 'НДС', width: '90px', className: 'text-right', sortKey: 'vat', cell: (r) => r.vatEnabled ? `${r.vat.toFixed(2)}%` : '—' })
  }

  const groupsTree = (
    <ProductGroupTree
      selectedId={filters.groupId}
      onSelect={(id) => { setFilters({ ...filters, groupId: id }); setPage(1); setGroupsOpen(false) }}
    />
  )

  return (
    <div className="flex h-full min-h-0">
      {/* Desktop groups tree — закреплён слева на md+. */}
      <aside className="hidden md:flex w-64 flex-shrink-0 border-r border-slate-200 dark:border-slate-800 bg-slate-50/60 dark:bg-slate-900/40 flex-col min-h-0">
        {groupsTree}
      </aside>

      {/* Mobile groups drawer. */}
      {groupsOpen && (
        <div className="md:hidden fixed inset-0 z-40" role="dialog" aria-modal="true">
          <div className="absolute inset-0 bg-slate-900/50 backdrop-blur-sm" onClick={() => setGroupsOpen(false)} />
          <aside className="absolute left-0 top-0 bottom-0 w-72 max-w-[85vw] bg-white dark:bg-slate-900 border-r border-slate-200 dark:border-slate-800 flex flex-col shadow-xl">
            <div className="h-12 flex items-center justify-between px-4 border-b border-slate-200 dark:border-slate-800">
              <span className="font-medium text-sm">Группы товаров</span>
              <button onClick={() => setGroupsOpen(false)} className="text-slate-500"><X className="w-5 h-5" /></button>
            </div>
            <div className="flex-1 min-h-0 overflow-auto">{groupsTree}</div>
          </aside>
        </div>
      )}

      {/* Right: products */}
      <div className="flex-1 min-w-0 flex flex-col">
        {/* Top bar */}
        <div className="px-4 sm:px-6 py-3 border-b border-slate-200 dark:border-slate-800 flex items-center gap-3 flex-wrap">
          <button
            onClick={() => setGroupsOpen(true)}
            className="md:hidden inline-flex items-center gap-1.5 text-sm text-slate-600 dark:text-slate-300 px-2 py-1 rounded border border-slate-200 dark:border-slate-700"
          >
            <FolderTree className="w-4 h-4" /> Группы
          </button>
          <div className="min-w-0">
            <h1 className="text-base font-semibold">Товары</h1>
            <p className="text-xs text-slate-500">
              {data ? `${data.total.toLocaleString('ru')} записей` : 'Каталог товаров и услуг'}
            </p>
          </div>
          <div className="ml-auto flex flex-wrap items-center gap-2">
            <SearchBar value={search} onChange={setSearch} placeholder="Поиск: название, артикул, штрихкод…" />
            <Button
              variant={filtersOpen || activeCount ? 'primary' : 'secondary'}
              onClick={() => setFiltersOpen((v) => !v)}
            >
              <Filter className="w-4 h-4" /> Фильтры{activeCount > 0 ? ` (${activeCount})` : ''}
            </Button>
            <Link to="/catalog/products/new">
              <Button><Plus className="w-4 h-4" /> Добавить</Button>
            </Link>
          </div>
        </div>

        {/* Filter panel */}
        {filtersOpen && (
          <div className="px-4 sm:px-6 py-3 border-b border-slate-200 dark:border-slate-800 bg-slate-50 dark:bg-slate-900/60 flex flex-wrap gap-3 sm:gap-4 items-center">
            {showService && (
              <Tri label="Услуга" value={filters.isService} onChange={(v) => { setFilters({ ...filters, isService: v }); setPage(1) }} />
            )}
            <div className="flex items-center gap-2 text-xs">
              <span className="text-slate-500">Фасовка</span>
              <select
                value={filters.packaging ?? ''}
                onChange={(e) => { const v = e.target.value; setFilters({ ...filters, packaging: v ? Number(v) : null }); setPage(1) }}
                className="rounded border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 px-2 py-0.5 text-xs"
              >
                <option value="">все</option>
                <option value="1">штучный</option>
                <option value="2">весовой</option>
                <option value="3">разливной</option>
              </select>
            </div>
            {showMarked && (
              <Tri label="Маркируемый" value={filters.isMarked} onChange={(v) => { setFilters({ ...filters, isMarked: v }); setPage(1) }} />
            )}
            <div className="flex items-center gap-2 text-xs">
              <span className="text-slate-500">{systemPriceType?.name ?? 'Цена'}</span>
              <div className="w-32">
                <MoneyInput
                  value={filters.systemPriceFrom}
                  onChange={(n) => { setFilters({ ...filters, systemPriceFrom: n }); setPage(1) }}
                  currencyCode={org.data?.defaultCurrencyCode ?? undefined}
                  currencySymbol={org.data?.defaultCurrencySymbol ?? undefined}
                  placeholder="от"
                />
              </div>
              <div className="w-32">
                <MoneyInput
                  value={filters.systemPriceTo}
                  onChange={(n) => { setFilters({ ...filters, systemPriceTo: n }); setPage(1) }}
                  currencyCode={org.data?.defaultCurrencyCode ?? undefined}
                  currencySymbol={org.data?.defaultCurrencySymbol ?? undefined}
                  placeholder="до"
                />
              </div>
            </div>
            {activeCount > 0 && (
              <button
                type="button"
                onClick={() => { setFilters(defaultFilters); setPage(1) }}
                className="text-xs text-slate-500 hover:text-slate-800 inline-flex items-center gap-1"
              >
                <X className="w-3.5 h-3.5" /> Сбросить
              </button>
            )}
          </div>
        )}

        {/* Table */}
        <div className="flex-1 min-h-0 overflow-auto">
          <DataTable
            rows={data?.items ?? []}
            isLoading={isLoading}
            rowKey={(r) => r.id}
            sortKey={sortKey}
            sortOrder={sortOrder}
            onSortChange={setSort}
            onRowClick={(r) => navigate(`/catalog/products/${r.id}`)}
            columns={baseColumns}
            empty="Товаров ещё нет. Они появятся после приёмки или через API."
          />
        </div>

        {data && data.total > 0 && (
          <div className="px-4 sm:px-6 py-3 border-t border-slate-200 dark:border-slate-800">
            <Pagination page={page} pageSize={data.pageSize} total={data.total} onPageChange={setPage} />
          </div>
        )}
      </div>
    </div>
  )
}
