import { useState, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import toast from 'react-hot-toast';
import { Search, Filter, Sparkles, EyeOff, Tag } from 'lucide-react';
import { api } from '../../lib/api-client';
import { AppShell, PageHeader, PageBody } from '../../layout/AppShell';
import { Button, Badge, Card, Input, Label, Select, Skeleton } from '../../components/ui/primitives';
import { Table, THead, TBody, TR, TH, TD } from '../../components/ui/table';
import { ProductDetailDrawer } from './ProductDetailDrawer';
import type { ProductRow, BrandCount } from './types';

const PAGE_SIZE = 50;

export function ProductsList() {
  const qc = useQueryClient();
  const [filters, setFilters] = useState({
    q: '',
    brand: '',
    is_sneaker: '' as '' | 'true' | 'false',
    in_stock: '' as '' | 'true' | 'false',
    has_ai_desc: '' as '' | 'true' | 'false',
    missing_image: '' as '' | 'true' | 'false',
  });
  const [page, setPage] = useState(0);
  const [selected, setSelected] = useState<Set<number>>(new Set());
  const [openProductId, setOpenProductId] = useState<number | null>(null);

  const params = useMemo(() => {
    const p: Record<string, unknown> = { limit: PAGE_SIZE, offset: page * PAGE_SIZE };
    for (const [k, v] of Object.entries(filters)) if (v) p[k] = v;
    return p;
  }, [filters, page]);

  const { data, isLoading } = useQuery({
    queryKey: ['products', params],
    queryFn: () => api.get<{ products: ProductRow[]; total: number; brands: BrandCount[] }>('/products', params),
  });

  const bulkMut = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      api.post<{ updated?: number; queued?: number; jobId?: number }>('/products/bulk', body),
    onSuccess: (res) => {
      if (res.jobId) toast.success(`${res.queued} producten in de wachtrij (job #${res.jobId})`);
      else toast.success(`${res.updated} producten bijgewerkt`);
      setSelected(new Set());
      qc.invalidateQueries({ queryKey: ['products'] });
    },
    onError: (e: Error) => toast.error(e.message),
  });

  function toggleAll() {
    if (!data?.products) return;
    if (selected.size === data.products.length) setSelected(new Set());
    else setSelected(new Set(data.products.map((p) => p.id)));
  }
  function toggleOne(id: number) {
    const next = new Set(selected);
    if (next.has(id)) next.delete(id);
    else next.add(id);
    setSelected(next);
  }

  const total = data?.total ?? 0;
  const products = data?.products ?? [];
  const brands = data?.brands ?? [];
  const maxPage = Math.max(0, Math.ceil(total / PAGE_SIZE) - 1);

  function updateFilter<K extends keyof typeof filters>(k: K, v: typeof filters[K]) {
    setFilters((f) => ({ ...f, [k]: v }));
    setPage(0);
  }

  return (
    <AppShell>
      <PageHeader title="Producten" description={`${total.toLocaleString('nl-NL')} producten in catalogus`} />
      <PageBody>
        <div className="grid grid-cols-12 gap-6">
          <aside className="col-span-3">
            <Card>
              <div className="px-5 py-4 border-b border-[#333] flex items-center gap-2">
                <Filter className="h-4 w-4 text-[#999]" />
                <span className="text-sm font-medium text-[#F5F5F5]">Filters</span>
              </div>
              <div className="px-5 py-4 space-y-4">
                <div>
                  <Label>Zoeken</Label>
                  <div className="relative mt-1">
                    <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-[#666]" />
                    <Input
                      className="pl-9"
                      value={filters.q}
                      onChange={(e) => updateFilter('q', e.target.value)}
                      placeholder="naam of merk..."
                    />
                  </div>
                </div>

                <div>
                  <Label>Merk</Label>
                  <Select
                    className="mt-1"
                    value={filters.brand}
                    onChange={(e) => updateFilter('brand', e.target.value)}
                  >
                    <option value="">Alle merken</option>
                    {brands.map((b) => (
                      <option key={b.brand} value={b.brand}>
                        {b.brand} ({b.count})
                      </option>
                    ))}
                  </Select>
                </div>

                <FilterTri label="Is sneaker" value={filters.is_sneaker} onChange={(v) => updateFilter('is_sneaker', v)} />
                <FilterTri label="Op voorraad" value={filters.in_stock} onChange={(v) => updateFilter('in_stock', v)} />
                <FilterTri label="AI-beschrijving" value={filters.has_ai_desc} onChange={(v) => updateFilter('has_ai_desc', v)} />
                <FilterTri label="Afbeelding ontbreekt" value={filters.missing_image} onChange={(v) => updateFilter('missing_image', v)} />

                <Button
                  variant="ghost"
                  size="sm"
                  className="w-full"
                  onClick={() =>
                    setFilters({ q: '', brand: '', is_sneaker: '', in_stock: '', has_ai_desc: '', missing_image: '' })
                  }
                >
                  Reset filters
                </Button>
              </div>
            </Card>
          </aside>

          <div className="col-span-9">
            {selected.size > 0 && (
              <Card className="mb-4 border-[#00FF6A]/30">
                <div className="px-5 py-3 flex items-center gap-3 flex-wrap">
                  <span className="text-sm text-[#F5F5F5]">
                    <strong>{selected.size}</strong> geselecteerd
                  </span>
                  <span className="text-[#333]">|</span>
                  <Button
                    size="sm"
                    variant="secondary"
                    onClick={() => bulkMut.mutate({ ids: [...selected], action: 'set-sneaker', is_sneaker: true })}
                    disabled={bulkMut.isPending}
                  >
                    <Tag className="h-4 w-4" />
                    Markeer als sneaker
                  </Button>
                  <Button
                    size="sm"
                    variant="secondary"
                    onClick={() => bulkMut.mutate({ ids: [...selected], action: 'hide' })}
                    disabled={bulkMut.isPending}
                  >
                    <EyeOff className="h-4 w-4" />
                    Verberg
                  </Button>
                  <Button
                    size="sm"
                    variant="secondary"
                    onClick={() => {
                      if (confirm(`AI-beschrijving regenereren voor ${selected.size} producten?`)) {
                        bulkMut.mutate({ ids: [...selected], action: 'regen-ai-desc' });
                      }
                    }}
                    disabled={bulkMut.isPending}
                  >
                    <Sparkles className="h-4 w-4" />
                    Regenereer AI-desc
                  </Button>
                  <div className="flex-1" />
                  <Button size="sm" variant="ghost" onClick={() => setSelected(new Set())}>
                    Annuleer
                  </Button>
                </div>
              </Card>
            )}

            <Card>
              {isLoading ? (
                <div className="p-6 space-y-3">
                  {[0, 1, 2, 3, 4].map((i) => (
                    <Skeleton key={i} className="h-12 w-full" />
                  ))}
                </div>
              ) : (
                <Table>
                  <THead>
                    <TR className="hover:bg-transparent">
                      <TH className="w-8">
                        <input
                          type="checkbox"
                          checked={products.length > 0 && selected.size === products.length}
                          onChange={toggleAll}
                        />
                      </TH>
                      <TH className="w-12"></TH>
                      <TH>Naam</TH>
                      <TH>Merk</TH>
                      <TH className="text-right">Prijs</TH>
                      <TH className="text-right">Aanbieders</TH>
                      <TH className="text-right">Clicks 7d</TH>
                      <TH>Status</TH>
                    </TR>
                  </THead>
                  <TBody>
                    {products.map((p) => (
                      <TR key={p.id} onClick={() => setOpenProductId(p.id)} className="cursor-pointer">
                        <TD onClick={(e) => e.stopPropagation()}>
                          <input type="checkbox" checked={selected.has(p.id)} onChange={() => toggleOne(p.id)} />
                        </TD>
                        <TD>
                          {p.image_url ? (
                            <img src={p.image_url} alt="" className="h-10 w-10 rounded object-cover bg-[#1A1A1A]" />
                          ) : (
                            <div className="h-10 w-10 rounded bg-[#1A1A1A] border border-[#333]" />
                          )}
                        </TD>
                        <TD>
                          <p className="font-medium text-[#F5F5F5] max-w-xs truncate">{p.name}</p>
                          {p.model_name && <p className="text-xs text-[#999]">{p.model_name}</p>}
                        </TD>
                        <TD className="text-xs text-[#999]">{p.brand ?? '—'}</TD>
                        <TD className="text-right tabular-nums">
                          {p.lowest_price > 0 ? `€${Number(p.lowest_price).toFixed(2)}` : <span className="text-[#666]">—</span>}
                        </TD>
                        <TD className="text-right tabular-nums">
                          {p.offer_count > 0 ? (
                            <span>{p.in_stock_count}/{p.offer_count}</span>
                          ) : (
                            <span className="text-[#666]">—</span>
                          )}
                        </TD>
                        <TD className="text-right tabular-nums text-xs text-[#999]">{p.clicks_7d ?? 0}</TD>
                        <TD>
                          <div className="flex items-center gap-1">
                            {p.is_sneaker && <Badge variant="success">sneaker</Badge>}
                            {p.has_ai_desc && <Badge variant="info">AI</Badge>}
                            {p.in_stock_count === 0 && <Badge variant="muted">geen stock</Badge>}
                          </div>
                        </TD>
                      </TR>
                    ))}
                  </TBody>
                </Table>
              )}

              {!isLoading && products.length > 0 && (
                <div className="px-5 py-3 border-t border-[#333] flex items-center justify-between text-xs">
                  <span className="text-[#999]">
                    {page * PAGE_SIZE + 1}–{Math.min((page + 1) * PAGE_SIZE, total)} van {total.toLocaleString('nl-NL')}
                  </span>
                  <div className="flex items-center gap-2">
                    <Button variant="ghost" size="sm" disabled={page === 0} onClick={() => setPage(page - 1)}>
                      Vorige
                    </Button>
                    <span className="text-[#999]">
                      {page + 1} / {maxPage + 1}
                    </span>
                    <Button variant="ghost" size="sm" disabled={page >= maxPage} onClick={() => setPage(page + 1)}>
                      Volgende
                    </Button>
                  </div>
                </div>
              )}
            </Card>
          </div>
        </div>
      </PageBody>

      {openProductId && (
        <ProductDetailDrawer
          productId={openProductId}
          onClose={() => setOpenProductId(null)}
          onSaved={() => qc.invalidateQueries({ queryKey: ['products'] })}
        />
      )}
    </AppShell>
  );
}

function FilterTri({
  label,
  value,
  onChange,
}: {
  label: string;
  value: '' | 'true' | 'false';
  onChange: (v: '' | 'true' | 'false') => void;
}) {
  return (
    <div>
      <Label>{label}</Label>
      <div className="mt-1 flex gap-1">
        {([['', 'alle'], ['true', 'ja'], ['false', 'nee']] as const).map(([v, l]) => (
          <button
            key={v}
            onClick={() => onChange(v)}
            className={`flex-1 h-8 rounded border text-xs font-medium transition-colors ${
              value === v
                ? 'border-[#00FF6A] text-[#00FF6A] bg-[#00FF6A]/5'
                : 'border-[#333] text-[#999] hover:text-[#F5F5F5]'
            }`}
          >
            {l}
          </button>
        ))}
      </div>
    </div>
  );
}
