import { type FormEvent, useEffect, useMemo, useState } from 'react';
import { Link as RouterLink, Navigate, useOutletContext, useParams } from 'react-router-dom';
import {
  AlertTriangle,
  ArrowLeft,
  ArrowRight,
  BarChart3,
  Boxes,
  ClipboardCheck,
  ClipboardList,
  Download,
  Link as LinkIcon,
  Package,
  PackageSearch,
  Pencil,
  RefreshCw,
  Repeat2,
  Ruler,
  Save,
  Search,
  Scissors,
  Truck,
  Trash2,
  Warehouse,
} from 'lucide-react';
import { buildConsumptionReferencePath } from '../catalogLinks';
import DateRangePicker from '../components/DateRangePicker';
import PaginationControls from '../components/PaginationControls';
import ProductTypeBadge from '../components/ProductTypeBadge';
import { classifyCutFamily } from '../analytics/cutting';
import { adjustSupplyLotInventory, approveSupplyReceipt, consumeSupplyLotForProduction, createSupplyFabricPlan, createSupplyReceipt, deleteSupplyFabricPlan, deleteSupplyReceipt, fetchCuttingSettings, fetchProductAnalytics, fetchStock, fetchSupplySummary } from '../dataService';
import { parseProductName } from '../productParsing';
import { resolveProductType, type ProductTypeKey } from '../productClassification';
import { getPlanningStock } from '../planningStock';
import type { CuttingSettings, DateRange, ProductAnalyticsItem, StockData, SupplyFabricPlan, SupplyLot, SupplyMovement, SupplyPurchaseNeed, SupplyReceipt, SupplySummary } from '../types';

type InventoryTab = 'dashboard' | 'stock' | 'balance' | 'receipts' | 'inventory' | 'movements';
type ReceiptView = 'new' | 'pending' | 'history';

const pageClassName = 'flex w-full flex-col gap-6';
const panelClassName = 'rounded-2xl border border-dark-border bg-dark-card shadow-sm';
const buttonClassName = 'inline-flex h-10 items-center justify-center gap-2 rounded-lg border border-dark-border bg-dark-input px-3 text-sm font-bold text-dark-text transition-colors hover:border-brand-primary cursor-pointer';
const inputClassName = 'h-10 w-full rounded-lg border border-dark-border bg-dark-input px-3 text-sm font-semibold text-dark-text outline-none placeholder:text-dark-muted focus:border-brand-primary';
const emptyStateClassName = 'flex min-h-[190px] flex-col items-center justify-center gap-2 px-4 py-10 text-center';

const emptySupplySummary: SupplySummary = {
  receipts: [],
  lots: [],
  movements: [],
  fabricPlans: [],
  purchaseNeeds: [],
  stats: {
    totalQuantityKg: 0,
    activeLots: 0,
    rolls: 0,
    alerts: 0,
    pendingReceipts: 0,
    approvedReceipts: 0,
  },
};

const formatNumber = (value: number, maximumFractionDigits = 2) => (
  new Intl.NumberFormat('pt-BR', { maximumFractionDigits }).format(value)
);

const parseDecimal = (value: string) => {
  const number = Number(value.replace(',', '.'));
  return Number.isFinite(number) ? number : 0;
};

const formatDateTime = (value: string | null) => {
  if (!value) return '-';
  return new Intl.DateTimeFormat('pt-BR', {
    day: '2-digit',
    month: '2-digit',
    year: '2-digit',
    hour: '2-digit',
    minute: '2-digit',
  }).format(new Date(value));
};

const normalizeSearch = (value: string) => value.normalize('NFD').replace(/[\u0300-\u036f]/g, '').toLowerCase();

const exportCsv = (filename: string, rows: Array<Record<string, string | number | null>>) => {
  if (!rows.length) return;
  const headers = Object.keys(rows[0]);
  const escapeCell = (value: string | number | null) => `"${String(value ?? '').replace(/"/g, '""')}"`;
  const csv = [
    headers.join(','),
    ...rows.map(row => headers.map(header => escapeCell(row[header])).join(',')),
  ].join('\n');
  const blob = new Blob([csv], { type: 'text/csv;charset=utf-8;' });
  const url = URL.createObjectURL(blob);
  const anchor = document.createElement('a');
  anchor.href = url;
  anchor.download = filename;
  anchor.click();
  URL.revokeObjectURL(url);
};

const inventoryTabs: Array<{ id: InventoryTab; name: string; icon: typeof BarChart3 }> = [
  { id: 'dashboard', name: 'Dashboard', icon: Warehouse },
  { id: 'stock', name: 'Estoque', icon: PackageSearch },
  { id: 'balance', name: 'Saldo', icon: BarChart3 },
  { id: 'receipts', name: 'Recebimentos', icon: Truck },
  { id: 'inventory', name: 'Inventário', icon: ClipboardCheck },
  { id: 'movements', name: 'Movimentações', icon: Repeat2 },
];

const receiptCategories: Array<{ name: string; icon: typeof Package }> = [
  { name: 'Malha / Tecido', icon: Ruler },
  { name: 'Embalagem', icon: Package },
  { name: 'Material de Limpeza', icon: Boxes },
  { name: 'Acessórios / Botões', icon: Warehouse },
  { name: 'Etiquetas', icon: LinkIcon },
  { name: 'Outro material', icon: ClipboardList },
];

type DemandQueue = 'apparel' | 'accessories' | 'inputs' | 'review' | 'dead';

type DemandRow = ProductAnalyticsItem & {
  productType: ProductTypeKey;
  color: string;
  size: string;
  dailySales: number;
  daysOfCover: number | null;
  targetDemand: number;
  suggestedUnits: number;
  missingData: string[];
  queue: DemandQueue;
};

const demandQueueLabels: Record<DemandQueue, string> = {
  apparel: 'Cortar / Repor',
  accessories: 'Repor acessórios',
  inputs: 'Comprar insumos',
  review: 'Revisar dados',
  dead: 'Estoque parado',
};

const demandQueueDescriptions: Record<DemandQueue, string> = {
  apparel: 'Produtos acabados com demanda ativa e cobertura abaixo da meta.',
  accessories: 'Acessórios acabados com demanda ativa e cobertura abaixo da meta.',
  inputs: 'Embalagens, matérias-primas e insumos de produção com necessidade de reposição.',
  review: 'SKUs com informações pendentes para qualificar o planejamento.',
  dead: 'Itens com saldo disponível e baixa movimentação no período.',
};

const directPurchaseTypes = new Set<ProductTypeKey>(['packaging', 'dtf_input', 'raw_material', 'machine_part']);

const planningReviewTypes = new Set<ProductTypeKey>(['unknown', 'kit_bundle']);

const Header = ({ title, subtitle, backTo }: { title: string; subtitle: string; backTo?: string }) => (
  <div className="flex flex-col gap-3">
    {backTo && (
      <RouterLink to={backTo} className="inline-flex w-fit items-center gap-2 text-sm font-bold text-dark-muted transition-colors hover:text-dark-text">
        <ArrowLeft className="h-4 w-4" />
        Suprimentos
      </RouterLink>
    )}
    <div>
      <h1 className="mb-2 text-2xl font-bold text-zinc-900 dark:text-dark-text">{title}</h1>
      <p className="font-medium text-zinc-500 dark:text-dark-muted">{subtitle}</p>
    </div>
  </div>
);

const ModuleCard = ({
  title,
  description,
  icon: Icon,
  to,
}: {
  title: string;
  description: string;
  icon: typeof Package;
  to: string;
}) => {
  return (
    <RouterLink to={to} className={`${panelClassName} flex min-h-32 items-start gap-4 p-5 transition-colors hover:border-brand-primary`}>
      <div className="flex h-11 w-11 items-center justify-center rounded-xl border border-dark-border bg-dark-input text-brand-primary">
        <Icon className="h-5 w-5" />
      </div>
      <div className="min-w-0 flex-1">
        <div className="flex items-start justify-between gap-3">
          <h2 className="text-base font-bold text-dark-text">{title}</h2>
          <ArrowRight className="mt-0.5 h-4 w-4 shrink-0 text-dark-muted" />
        </div>
        <p className="mt-2 text-sm font-semibold text-dark-muted">{description}</p>
      </div>
    </RouterLink>
  );
};

const SuppliesHub = () => (
  <div className={pageClassName}>
    <Header title="Suprimentos" subtitle="Corte, estoque, malha e compras em um fluxo operacional." />
    <div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
      <ModuleCard title="Planejamento Operacional" description="Prioridades de reposição, compra e revisão calculadas por demanda, estoque e cobertura." icon={PackageSearch} to="/supplies/current-planning" />
      <ModuleCard title="Planejamento de Corte" description="Ruptura por cor e tamanho, montagem do corte e prioridade por cobertura." icon={Scissors} to="/cutting" />
      <ModuleCard title="Controle de Estoque" description="Saldo, lotes, recebimentos, inventário e movimentações." icon={Package} to="/supplies/inventory" />
      <ModuleCard title="Ordens de Produção" description="Ordens geradas pelo corte e acompanhamento de produção." icon={ClipboardList} to="/production-orders" />
      <ModuleCard title="Planejamento de Malha" description="Fila de matéria-prima para compra, recebimento e abastecimento do corte." icon={Ruler} to="/supplies/fabric-planning" />
      <ModuleCard title="Necessidade de Compra" description="Itens abaixo do mínimo e necessidade projetada para compra." icon={BarChart3} to="/supplies/purchase-needs" />
    </div>
  </div>
);

const getRangeDays = (range: DateRange) => {
  const start = new Date(range.start);
  const end = new Date(range.end);
  start.setHours(0, 0, 0, 0);
  end.setHours(0, 0, 0, 0);
  return Math.max(1, Math.round((end.getTime() - start.getTime()) / 86_400_000) + 1);
};

const formatDays = (value: number | null) => {
  if (value === null) return '-';
  if (value > 999) return '999+ dias';
  return `${formatNumber(value, value < 10 ? 1 : 0)} dias`;
};

const buildDemandRow = (
  product: ProductAnalyticsItem,
  settings: CuttingSettings,
  rangeDays: number,
  targetCoverageDays: number
): DemandRow => {
  const override = settings.productOverrides[product.id];
  const metadata = parseProductName(product.name);
  const productType = resolveProductType(product.name, override);
  const color = override?.color || metadata.color;
  const size = (override?.size || metadata.size).toUpperCase();
  const dailySales = product.quantitySold / rangeDays;
  const planningStock = getPlanningStock(product.stock);
  const daysOfCover = dailySales > 0 ? planningStock / dailySales : null;
  const targetDemand = dailySales * targetCoverageDays;
  const suggestedUnits = Math.max(0, Math.ceil(targetDemand - planningStock));
  const missingData: string[] = [];

  if (planningReviewTypes.has(productType)) missingData.push('tipo');
  if (productType === 'finished_apparel') {
    if (!color) missingData.push('cor');
    if (!size) missingData.push('tamanho');
    if ((override?.familyKey || classifyCutFamily(metadata.baseName).key) === 'OUTROS') missingData.push('família');
  }

  let queue: DemandQueue = 'review';
  if (product.stock > 0 && (dailySales === 0 || (daysOfCover !== null && daysOfCover > 120))) {
    queue = 'dead';
  } else if (missingData.length) {
    queue = 'review';
  } else if (productType === 'finished_apparel') {
    queue = 'apparel';
  } else if (productType === 'finished_accessory') {
    queue = 'accessories';
  } else if (directPurchaseTypes.has(productType)) {
    queue = 'inputs';
  }

  return {
    ...product,
    productType,
    color,
    size,
    dailySales,
    daysOfCover,
    targetDemand,
    suggestedUnits,
    missingData,
    queue,
  };
};

const DemandPlanningScreen = () => {
  const { dateRange, setDateRange } = useOutletContext<{
    dateRange: DateRange,
    setDateRange: (range: DateRange) => void
  }>();
  const [products, setProducts] = useState<ProductAnalyticsItem[]>([]);
  const [settings, setSettings] = useState<CuttingSettings>({ familyYields: {}, productOverrides: {} });
  const [isLoading, setIsLoading] = useState(true);
  const [queue, setQueue] = useState<DemandQueue>('apparel');
  const [search, setSearch] = useState('');
  const [targetCoverageDays, setTargetCoverageDays] = useState(30);
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  useEffect(() => {
    let isMounted = true;

    const load = async () => {
      setIsLoading(true);
      const [productData, planningSettings] = await Promise.all([
        fetchProductAnalytics(dateRange),
        fetchCuttingSettings(),
      ]);

      if (isMounted) {
        setProducts(productData);
        setSettings(planningSettings);
        setIsLoading(false);
      }
    };

    void load();

    return () => {
      isMounted = false;
    };
  }, [dateRange]);

  const rows = useMemo(() => {
    const rangeDays = getRangeDays(dateRange);
    return products.map(product => buildDemandRow(product, settings, rangeDays, targetCoverageDays));
  }, [dateRange, products, settings, targetCoverageDays]);

  const queueRows = useMemo(() => {
    const normalizedSearch = normalizeSearch(search);
    return rows
      .filter(row => row.queue === queue)
      .filter(row => {
        if (queue === 'dead') return row.stock > 0;
        if (queue === 'review') return row.quantitySold > 0 || row.stock > 0;
        return row.dailySales > 0 && (row.suggestedUnits > 0 || (row.daysOfCover !== null && row.daysOfCover <= targetCoverageDays));
      })
      .filter(row => (
        !normalizedSearch || normalizeSearch(`${row.id} ${row.name} ${row.color} ${row.size} ${row.missingData.join(' ')}`).includes(normalizedSearch)
      ))
      .sort((a, b) => {
        if (queue === 'dead') {
          return (b.stock * b.lastPrice) - (a.stock * a.lastPrice);
        }
        if (queue === 'review') {
          if (b.quantitySold !== a.quantitySold) return b.quantitySold - a.quantitySold;
          return b.revenue - a.revenue;
        }
        if (b.suggestedUnits !== a.suggestedUnits) return b.suggestedUnits - a.suggestedUnits;
        return b.dailySales - a.dailySales;
      });
  }, [queue, rows, search, targetCoverageDays]);

  const queueStats = useMemo(() => {
    return (Object.keys(demandQueueLabels) as DemandQueue[]).reduce<Record<DemandQueue, number>>((acc, item) => {
      acc[item] = rows.filter(row => {
        if (row.queue !== item) return false;
        if (item === 'dead') return row.stock > 0;
        if (item === 'review') return row.quantitySold > 0 || row.stock > 0;
        return row.dailySales > 0 && (row.suggestedUnits > 0 || (row.daysOfCover !== null && row.daysOfCover <= targetCoverageDays));
      }).length;
      return acc;
    }, { apparel: 0, accessories: 0, inputs: 0, review: 0, dead: 0 });
  }, [rows, targetCoverageDays]);

  const totalPages = Math.ceil(queueRows.length / itemsPerPage);
  const safeCurrentPage = Math.min(currentPage, totalPages || 1);
  const startIndex = (safeCurrentPage - 1) * itemsPerPage;
  const paginatedRows = queueRows.slice(startIndex, startIndex + itemsPerPage);
  const suggestedTotal = queueRows.reduce((total, row) => total + (queue === 'dead' ? row.stock * row.lastPrice : row.suggestedUnits), 0);

  return (
    <div className={pageClassName}>
      <div className="grid grid-cols-1 gap-4 2xl:grid-cols-[minmax(520px,1fr)_auto] 2xl:items-start">
        <Header title="Planejamento Operacional" subtitle="Prioridades de reposição, compra e revisão calculadas por demanda, estoque e cobertura." backTo="/supplies" />
        <DateRangePicker
          dateRange={dateRange}
          onChange={(range) => {
            setDateRange(range);
            setCurrentPage(1);
          }}
        />
      </div>

      <div className="grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-5">
        {(Object.keys(demandQueueLabels) as DemandQueue[]).map(item => (
          <button
            key={item}
            type="button"
            onClick={() => {
              setQueue(item);
              setCurrentPage(1);
            }}
            className={`rounded-2xl border p-4 text-left transition-colors cursor-pointer ${
              queue === item ? 'border-brand-primary/45 bg-brand-primary/10' : 'border-dark-border bg-dark-card hover:border-brand-primary/35'
            }`}
          >
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">{demandQueueLabels[item]}</p>
            <p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(queueStats[item], 0)}</p>
            <p className="mt-1 line-clamp-2 text-xs font-semibold text-dark-muted">{demandQueueDescriptions[item]}</p>
          </button>
        ))}
      </div>

      <div className="grid grid-cols-1 gap-3 rounded-2xl border border-dark-border bg-dark-card p-4 shadow-sm xl:grid-cols-[minmax(360px,1fr)_auto] xl:items-center">
        <div className="flex flex-col gap-4 xl:flex-row xl:items-center xl:justify-between">
          <div>
            <h2 className="text-base font-bold text-dark-text">{demandQueueLabels[queue]}</h2>
            <p className="mt-1 text-sm font-semibold text-dark-muted">{demandQueueDescriptions[queue]}</p>
          </div>
        </div>
        <div className="flex flex-col gap-2 sm:flex-row xl:justify-end">
            <label className="relative min-w-72">
              <Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
              <input
                value={search}
                onChange={(event) => {
                  setSearch(event.target.value);
                  setCurrentPage(1);
                }}
                className={`${inputClassName} pl-9`}
                placeholder="Buscar SKU, produto, cor..."
              />
            </label>
            <select
              value={targetCoverageDays}
              onChange={(event) => {
                setTargetCoverageDays(Number(event.target.value));
                setCurrentPage(1);
              }}
              className={inputClassName}
              title="Cobertura alvo"
            >
              {[15, 30, 45, 60].map(days => <option key={days} value={days}>{days} dias</option>)}
            </select>
            <button
              type="button"
              onClick={() => exportCsv('planejamento-dados-atuais.csv', queueRows.map(row => ({
                fila: demandQueueLabels[queue],
                sku: row.id,
                produto: row.name,
                tipo: row.productType,
                cor: row.color,
                tamanho: row.size,
                vendido: row.quantitySold,
                estoque: row.stock,
                media_diaria: row.dailySales.toFixed(2).replace('.', ','),
                cobertura_dias: row.daysOfCover === null ? '' : row.daysOfCover.toFixed(1).replace('.', ','),
                sugestao_unidades: row.suggestedUnits,
                pendencias: row.missingData.join(' | '),
              })))}
              className={buttonClassName}
            >
              <Download className="h-4 w-4" />
              CSV
            </button>
        </div>
      </div>

      <div className="grid grid-cols-1 gap-3 md:grid-cols-3">
          <div className="rounded-xl border border-dark-border bg-dark-input/35 p-4">
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Itens na fila</p>
            <p className="mt-2 text-2xl font-bold text-dark-text">{formatNumber(queueRows.length, 0)}</p>
          </div>
          <div className="rounded-xl border border-dark-border bg-dark-input/35 p-4">
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">{queue === 'dead' ? 'Valor em estoque' : 'Unidades sugeridas'}</p>
            <p className="mt-2 text-2xl font-bold text-dark-text">
              {queue === 'dead'
                ? new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(suggestedTotal)
                : `${formatNumber(suggestedTotal, 0)} un.`}
            </p>
          </div>
          <div className="rounded-xl border border-dark-border bg-dark-input/35 p-4">
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Cobertura alvo</p>
            <p className="mt-2 text-2xl font-bold text-dark-text">{targetCoverageDays} dias</p>
          </div>
      </div>

        {isLoading ? (
          <div className={`${panelClassName} ${emptyStateClassName}`}>
            <PackageSearch className="h-8 w-8 text-brand-primary" />
            <h3 className="text-base font-bold text-dark-text">Carregando dados de produtos...</h3>
          </div>
        ) : queueRows.length ? (
          <div className="overflow-hidden rounded-2xl border border-dark-border bg-dark-card shadow-sm">
            <div className="overflow-x-auto">
              <table className="w-full min-w-[1080px] table-fixed border-collapse">
                <colgroup>
                  <col className="w-[120px]" />
                  <col />
                  <col className="w-[140px]" />
                  <col className="w-[120px]" />
                  <col className="w-[120px]" />
                  <col className="w-[120px]" />
                  <col className="w-[130px]" />
                  <col className="w-[100px]" />
                </colgroup>
                <thead className="border-b border-dark-border bg-dark-header text-xs font-bold uppercase tracking-widest text-dark-muted">
                  <tr>
                    <th scope="col" className="px-4 py-3 text-left">SKU</th>
                    <th scope="col" className="px-4 py-3 text-left">Produto</th>
                    <th scope="col" className="px-4 py-3 text-left">Tipo</th>
                    <th scope="col" className="px-4 py-3 text-right">Média/dia</th>
                    <th scope="col" className="px-4 py-3 text-right">Estoque</th>
                    <th scope="col" className="px-4 py-3 text-right">Cobertura</th>
                    <th scope="col" className="px-4 py-3 text-right">{queue === 'dead' ? 'Valor estoque' : 'Sugestão'}</th>
                    <th scope="col" className="px-4 py-3 text-right">Ações</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-dark-border">
                  {paginatedRows.map(row => (
                    <tr key={row.id} className="transition-colors hover:bg-dark-input/50">
                      <td className="px-4 py-2.5 font-mono text-[11px] text-dark-muted">#{row.id}</td>
                      <td className="px-4 py-2.5">
                        <p className="truncate text-sm font-bold text-dark-text" title={row.name}>{row.name}</p>
                        <p className="mt-1 truncate text-xs font-semibold text-dark-muted">
                          Cor: {row.color || '-'} · Tam.: {row.size || '-'}
                          {row.missingData.length ? ` · Falta: ${row.missingData.join(', ')}` : ''}
                        </p>
                      </td>
                      <td className="px-4 py-2.5"><ProductTypeBadge type={row.productType} /></td>
                      <td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatNumber(row.dailySales, 2)}</td>
                      <td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatNumber(row.stock, 0)} un.</td>
                      <td className="px-4 py-2.5 text-right text-sm font-bold text-dark-text">{formatDays(row.daysOfCover)}</td>
                      <td className={`px-4 py-2.5 text-right text-sm font-bold ${queue === 'dead' ? 'text-amber-300' : row.suggestedUnits > 0 ? 'text-amber-300' : 'text-emerald-300'}`}>
                        {queue === 'dead'
                          ? new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(row.stock * row.lastPrice)
                          : `${formatNumber(row.suggestedUnits, 0)} un.`}
                      </td>
                      <td className="px-4 py-2.5 text-right">
                        <div className="flex justify-end gap-2">
                          {queue === 'review' && (
                            <RouterLink
                              to="/planning-issues"
                              className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-dark-input text-dark-text transition-colors hover:bg-dark-border"
                              title="Abrir dados pendentes"
                              aria-label="Abrir dados pendentes"
                            >
                              <Pencil className="h-3.5 w-3.5" />
                            </RouterLink>
                          )}
                          <RouterLink
                            to={`/products/${row.id}`}
                            className="inline-flex h-8 w-8 items-center justify-center rounded-lg bg-brand-primary/10 text-brand-primary transition-opacity hover:opacity-80"
                            title={`Ver SKU ${row.id}`}
                            aria-label={`Ver SKU ${row.id}`}
                          >
                            <ArrowRight className="h-3.5 w-3.5" />
                          </RouterLink>
                        </div>
                      </td>
                    </tr>
                  ))}
                </tbody>
              </table>
            </div>
            <PaginationControls
              totalItems={queueRows.length}
              currentPage={safeCurrentPage}
              totalPages={totalPages}
              pageSize={itemsPerPage}
              pageSizeOptions={[10, 20, 50, 100]}
              itemLabel="SKUs"
              pageSizeLabel="itens por página"
              startIndex={startIndex}
              endIndex={Math.min(startIndex + itemsPerPage, queueRows.length)}
              onPageChange={setCurrentPage}
              onPageSizeChange={(pageSize) => {
                setItemsPerPage(pageSize);
                setCurrentPage(1);
              }}
              className="border-t border-dark-border px-4 py-3"
            />
          </div>
        ) : (
          <div className={`${panelClassName} ${emptyStateClassName}`}>
            <PackageSearch className="h-8 w-8 text-brand-primary" />
            <h3 className="text-base font-bold text-dark-text">Nada nesta fila</h3>
            <p className="text-sm font-semibold text-dark-muted">Ajuste a busca, período ou cobertura alvo.</p>
          </div>
        )}
    </div>
  );
};

const StatGrid = ({ summary }: { summary: SupplySummary }) => {
  const stats = [
    { label: 'Total em estoque', value: `${formatNumber(summary.stats.totalQuantityKg)} kg` },
    { label: 'Lotes ativos', value: `${summary.stats.activeLots}` },
    { label: 'Rolos', value: `${formatNumber(summary.stats.rolls, 0)}` },
    { label: 'Alertas', value: `${summary.stats.alerts}` },
  ];

  return (
  <div className="grid grid-cols-2 gap-3 lg:grid-cols-4">
    {stats.map(stat => (
      <div key={stat.label} className="rounded-xl border border-dark-border bg-dark-input/40 px-4 py-4 text-center">
        <p className="text-2xl font-bold text-dark-text">{stat.value}</p>
        <p className="mt-1 text-xs font-semibold text-dark-muted">{stat.label}</p>
      </div>
    ))}
  </div>
  );
};

const InventoryDashboard = ({ summary, onNewReceipt }: { summary: SupplySummary; onNewReceipt: () => void }) => {
  const categories = summary.lots.reduce<Record<string, { quantity: number; unit: string; lots: number }>>((acc, lot) => {
    const current = acc[lot.category] || { quantity: 0, unit: lot.unit, lots: 0 };
    acc[lot.category] = {
      quantity: current.quantity + lot.quantity,
      unit: current.unit === lot.unit ? lot.unit : 'mix',
      lots: current.lots + 1,
    };
    return acc;
  }, {});
  const latestReceipts = summary.receipts.slice(0, 4);

  return (
  <div className="space-y-4">
    <StatGrid summary={summary} />
    <div className={`${panelClassName} p-5`}>
      <h2 className="text-base font-bold text-dark-text">Por categoria de material</h2>
      {Object.keys(categories).length ? (
        <div className="mt-4 grid grid-cols-1 gap-3 md:grid-cols-2">
          {Object.entries(categories).map(([category, data]) => (
            <div key={category} className="rounded-xl border border-dark-border bg-dark-input/35 p-4">
              <p className="text-sm font-bold text-dark-text">{category}</p>
              <p className="mt-2 text-2xl font-bold text-dark-text">{formatNumber(data.quantity)} {data.unit}</p>
              <p className="mt-1 text-xs font-semibold text-dark-muted">{data.lots} lote(s) ativo(s)</p>
            </div>
          ))}
        </div>
      ) : (
        <div className={emptyStateClassName}>
          <Warehouse className="h-8 w-8 text-brand-primary" />
          <h3 className="text-base font-bold text-dark-text">Nenhuma categoria com saldo</h3>
          <p className="text-sm font-semibold text-dark-muted">Registre entradas para agrupar o estoque por tipo de material.</p>
        </div>
      )}
    </div>
    <div className={`${panelClassName} p-5`}>
      <h2 className="flex items-center gap-2 text-base font-bold text-dark-text"><AlertTriangle className="h-4 w-4 text-yellow-400" /> Alertas de estoque</h2>
      <p className="mt-4 text-sm font-semibold text-dark-muted">Nenhum alerta no momento.</p>
    </div>
    <div className={`${panelClassName} p-5`}>
      <div className="flex items-center justify-between gap-3">
        <h2 className="text-base font-bold text-dark-text">Últimas entradas</h2>
        <button type="button" onClick={onNewReceipt} className={buttonClassName}>Nova entrada</button>
      </div>
      {latestReceipts.length ? (
        <div className="mt-4 divide-y divide-dark-border overflow-hidden rounded-xl border border-dark-border">
          {latestReceipts.map(receipt => (
            <div key={receipt.id} className="grid grid-cols-1 gap-2 bg-dark-input/25 p-3 md:grid-cols-[1fr_auto_auto] md:items-center">
              <div>
                <p className="text-sm font-bold text-dark-text">{receipt.product}</p>
                <p className="text-xs font-semibold text-dark-muted">{receipt.category} · {formatDateTime(receipt.createdAt)}</p>
              </div>
              <p className="text-sm font-bold text-dark-text">{formatNumber(receipt.quantity)} {receipt.unit}</p>
              <span className={`w-fit rounded-full border px-2.5 py-1 text-xs font-bold ${
                receipt.status === 'approved'
                  ? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-300'
                  : 'border-amber-400/30 bg-amber-400/10 text-amber-300'
              }`}>
                {receipt.status === 'approved' ? 'Aprovado' : 'Pendente'}
              </span>
            </div>
          ))}
        </div>
      ) : (
        <p className="mt-5 text-sm font-semibold text-dark-muted">Nenhuma entrada registrada.</p>
      )}
    </div>
  </div>
  );
};

const BalanceTab = ({ summary, onRefresh }: { summary: SupplySummary; onRefresh: () => void }) => {
  const [search, setSearch] = useState('');
  const [category, setCategory] = useState('all');
  const [supplier, setSupplier] = useState('all');
  const categories = Array.from(new Set(summary.lots.map(lot => lot.category))).sort();
  const suppliers = Array.from(new Set(summary.lots.map(lot => lot.supplier || 'Sem fornecedor'))).sort();
  const normalizedSearch = normalizeSearch(search);
  const visibleLots = summary.lots.filter(lot => {
    const lotSupplier = lot.supplier || 'Sem fornecedor';
    const matchesSearch = !normalizedSearch || normalizeSearch(`${lot.product} ${lot.category} ${lotSupplier} ${lot.invoice} ${lot.id}`).includes(normalizedSearch);
    const matchesCategory = category === 'all' || lot.category === category;
    const matchesSupplier = supplier === 'all' || lotSupplier === supplier;
    return matchesSearch && matchesCategory && matchesSupplier;
  });

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap gap-2">
        <button
          type="button"
          onClick={() => exportCsv('saldo-suprimentos.csv', visibleLots.map(lot => ({
            lote: lot.id,
            material: lot.product,
            categoria: lot.category,
            quantidade: lot.quantity,
            unidade: lot.unit,
            fornecedor: lot.supplier || 'Sem fornecedor',
            nota_fiscal: lot.invoice || '',
            criado_em: lot.createdAt,
          })))}
          className={buttonClassName}
        >
          <Download className="h-4 w-4" /> Exportar saldo CSV
        </button>
        <button type="button" onClick={onRefresh} className={buttonClassName}><RefreshCw className="h-4 w-4" /> Atualizar saldo</button>
      </div>
      <div className={`${panelClassName} p-4`}>
        <div className="grid grid-cols-1 gap-3 lg:grid-cols-[1fr_220px_220px]">
          <label className="relative">
            <Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
            <input value={search} onChange={(event) => setSearch(event.target.value)} className={`${inputClassName} pl-9`} placeholder="Buscar por SKU, lote, tipo ou fornecedor..." />
          </label>
          <select value={category} onChange={(event) => setCategory(event.target.value)} className={inputClassName}>
            <option value="all">Todos os tipos</option>
            {categories.map(item => <option key={item} value={item}>{item}</option>)}
          </select>
          <select value={supplier} onChange={(event) => setSupplier(event.target.value)} className={inputClassName}>
            <option value="all">Todos os fornecedores</option>
            {suppliers.map(item => <option key={item} value={item}>{item}</option>)}
          </select>
        </div>
      </div>
    <div className={`${panelClassName} p-5`}>
      <StatGrid summary={summary} />
    </div>
    <div className={`${panelClassName} p-5`}>
      <div className="flex items-center justify-between gap-3">
        <h2 className="text-base font-bold text-dark-text">Saldo por tipo</h2>
        <span className="text-xs font-semibold text-dark-muted">Clique para expandir lotes</span>
      </div>
      {visibleLots.length ? (
        <div className="mt-4 overflow-hidden rounded-xl border border-dark-border">
          <div className="hidden grid-cols-[1.2fr_1fr_120px_1fr_140px] border-b border-dark-border bg-dark-input/40 px-4 py-3 text-xs font-bold uppercase tracking-widest text-dark-muted md:grid">
            <span>Material</span>
            <span>Categoria</span>
            <span>Saldo</span>
            <span>Fornecedor</span>
            <span>Lote</span>
          </div>
          <div className="divide-y divide-dark-border">
            {visibleLots.map(lot => (
              <div key={lot.id} className="grid grid-cols-1 gap-2 bg-dark-card px-4 py-3 md:grid-cols-[1.2fr_1fr_120px_1fr_140px] md:items-center">
                <p className="text-sm font-bold text-dark-text">{lot.product}</p>
                <p className="text-sm font-semibold text-dark-muted">{lot.category}</p>
                <p className="text-sm font-bold text-dark-text">{formatNumber(lot.quantity)} {lot.unit}</p>
                <p className="text-sm font-semibold text-dark-muted">{lot.supplier || 'Sem fornecedor'}</p>
                <p className="text-xs font-bold text-dark-muted">#{lot.id} · {lot.invoice || 'sem NF'}</p>
              </div>
            ))}
          </div>
        </div>
      ) : (
        <div className={emptyStateClassName}>
          <Package className="h-8 w-8 text-brand-primary" />
          <h3 className="text-base font-bold text-dark-text">{summary.lots.length ? 'Nenhum lote encontrado' : 'Nenhum item em estoque'}</h3>
          <p className="text-sm font-semibold text-dark-muted">{summary.lots.length ? 'Ajuste a busca ou os filtros.' : 'Registre entradas para ver o saldo aqui.'}</p>
        </div>
      )}
    </div>
  </div>
  );
};

const ReceiptList = ({
  receipts,
  emptyTitle,
  onApprove,
  onRemove,
}: {
  receipts: SupplyReceipt[];
  emptyTitle: string;
  onApprove: (receiptId: number) => void;
  onRemove: (receiptId: number) => void;
}) => (
  <div className={`${panelClassName} overflow-hidden`}>
    {receipts.length ? (
      <div className="divide-y divide-dark-border">
        {receipts.map(receipt => (
          <div key={receipt.id} className="grid grid-cols-1 gap-3 p-4 lg:grid-cols-[1.2fr_120px_1fr_100px_auto] lg:items-center">
            <div>
              <p className="font-bold text-dark-text">{receipt.product}</p>
              <p className="text-xs font-semibold text-dark-muted">{receipt.category} · {receipt.invoice ? `NF ${receipt.invoice}` : 'sem NF'} · {formatDateTime(receipt.createdAt)}</p>
            </div>
            <p className="text-sm font-bold text-dark-text">{formatNumber(receipt.quantity)} {receipt.unit}</p>
            <p className="text-sm font-semibold text-dark-muted">{receipt.supplier}</p>
            <span className={`w-fit rounded-full border px-2.5 py-1 text-xs font-bold ${
              receipt.status === 'approved'
                ? 'border-emerald-400/30 bg-emerald-400/10 text-emerald-300'
                : 'border-amber-400/30 bg-amber-400/10 text-amber-300'
            }`}>
              {receipt.status === 'approved' ? 'Aprovado' : 'Pendente'}
            </span>
            <div className="flex flex-wrap gap-2 lg:justify-end">
              {receipt.status === 'pending' && (
                <button type="button" onClick={() => onApprove(receipt.id)} className={buttonClassName}>
                  Aprovar
                </button>
              )}
              <button type="button" onClick={() => onRemove(receipt.id)} className="inline-flex h-10 items-center justify-center rounded-lg px-3 text-sm font-bold text-red-400 transition-colors hover:bg-red-500/10 cursor-pointer">
                Remover
              </button>
            </div>
          </div>
        ))}
      </div>
    ) : (
      <div className={emptyStateClassName}>
        <Truck className="h-8 w-8 text-brand-primary" />
        <h3 className="text-base font-bold text-dark-text">{emptyTitle}</h3>
        <p className="text-sm font-semibold text-dark-muted">Registre um recebimento para preencher esta lista.</p>
      </div>
    )}
  </div>
);

const ReceiptsTab = ({
  receipts,
  onCreate,
  onApprove,
  onRemove,
  isBusy,
}: {
  receipts: SupplyReceipt[];
  onCreate: (payload: { category: string; product: string; quantity: number; unit: string; supplier: string; invoice: string; notes: string }) => Promise<void>;
  onApprove: (receiptId: number) => Promise<void>;
  onRemove: (receiptId: number) => Promise<void>;
  isBusy: boolean;
}) => {
  const [activeView, setActiveView] = useState<ReceiptView>('new');
  const [selectedCategory, setSelectedCategory] = useState(receiptCategories[0].name);
  const [form, setForm] = useState({
    product: '',
    quantity: '',
    unit: 'kg',
    supplier: '',
    invoice: '',
    notes: '',
  });

  const pendingReceipts = receipts.filter(receipt => receipt.status === 'pending');
  const visibleReceipts = activeView === 'pending' ? pendingReceipts : receipts;

  const handleReceiptSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const product = form.product.trim();
    const quantity = parseDecimal(form.quantity);
    if (!product || quantity <= 0) return;

    await onCreate({
      category: selectedCategory,
      product,
      quantity,
      unit: form.unit,
      supplier: form.supplier.trim() || 'Sem fornecedor',
      invoice: form.invoice.trim(),
      notes: form.notes.trim(),
    });
    setForm({ product: '', quantity: '', unit: 'kg', supplier: '', invoice: '', notes: '' });
    setActiveView('pending');
  };

  return (
    <div className="space-y-4">
      <div className="flex flex-wrap gap-2">
        {[
          { id: 'new', label: 'Novo recebimento' },
          { id: 'pending', label: `Pendentes (${pendingReceipts.length})` },
          { id: 'history', label: `Histórico (${receipts.length})` },
        ].map(item => (
          <button
            key={item.id}
            type="button"
            onClick={() => setActiveView(item.id as ReceiptView)}
            className={`${buttonClassName} ${activeView === item.id ? 'border-brand-primary bg-brand-primary text-brand-contrast' : ''}`}
          >
            {item.label}
          </button>
        ))}
      </div>

      {activeView === 'new' && (
        <form onSubmit={handleReceiptSubmit} className={`${panelClassName} p-5`}>
          <h2 className="text-base font-bold text-dark-text">Registrar recebimento</h2>
          <div className="mt-4 rounded-xl border border-dark-border bg-dark-input px-4 py-3 text-sm font-semibold text-dark-muted">
            Preencha o que chegou. O financeiro vincula OC/NF e aprova o lançamento.
          </div>
          <p className="mt-5 text-xs font-bold uppercase tracking-widest text-dark-muted">1. Qual categoria de produto chegou?</p>
          <div className="mt-3 grid grid-cols-1 gap-3 sm:grid-cols-2">
            {receiptCategories.map(category => (
              <button
                key={category.name}
                type="button"
                onClick={() => setSelectedCategory(category.name)}
                className={`flex min-h-24 flex-col items-center justify-center gap-3 rounded-xl border p-4 text-center font-bold transition-colors cursor-pointer ${
                  selectedCategory === category.name
                    ? 'border-brand-primary bg-brand-primary/12 text-brand-primary'
                    : 'border-dark-border bg-dark-input/40 text-dark-text hover:border-brand-primary'
                }`}
              >
                <category.icon className="h-6 w-6" />
                {category.name}
              </button>
            ))}
          </div>

          <div className="mt-5 rounded-xl border border-dark-border bg-dark-input/35 p-4">
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">2. Detalhes do recebimento</p>
            <div className="mt-3 grid grid-cols-1 gap-3 md:grid-cols-2">
              <label className="text-xs font-bold text-dark-muted">
                Produto / material
                <input value={form.product} onChange={(event) => setForm(current => ({ ...current, product: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: Meia malha 30.1" />
              </label>
              <label className="text-xs font-bold text-dark-muted">
                Fornecedor
                <input value={form.supplier} onChange={(event) => setForm(current => ({ ...current, supplier: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="Opcional" />
              </label>
              <label className="text-xs font-bold text-dark-muted">
                Quantidade
                <input inputMode="decimal" value={form.quantity} onChange={(event) => setForm(current => ({ ...current, quantity: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: 120" />
              </label>
              <label className="text-xs font-bold text-dark-muted">
                Unidade
                <select value={form.unit} onChange={(event) => setForm(current => ({ ...current, unit: event.target.value }))} className={`${inputClassName} mt-1`}>
                  <option value="kg">kg</option>
                  <option value="rolos">rolos</option>
                  <option value="un.">un.</option>
                  <option value="caixas">caixas</option>
                </select>
              </label>
              <label className="text-xs font-bold text-dark-muted">
                Nota fiscal
                <input value={form.invoice} onChange={(event) => setForm(current => ({ ...current, invoice: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="NF-001234" />
              </label>
              <label className="text-xs font-bold text-dark-muted md:col-span-2">
                Observações
                <textarea value={form.notes} onChange={(event) => setForm(current => ({ ...current, notes: event.target.value }))} className="mt-1 min-h-20 w-full rounded-lg border border-dark-border bg-dark-input px-3 py-2 text-sm font-semibold text-dark-text outline-none placeholder:text-dark-muted focus:border-brand-primary" placeholder="Condição, divergências, lote..." />
              </label>
            </div>
            <button type="submit" disabled={isBusy} className="mt-4 inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg bg-brand-primary px-4 text-sm font-bold text-brand-contrast transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer">
              <Save className="h-4 w-4" />
              {isBusy ? 'Salvando...' : 'Registrar recebimento'}
            </button>
          </div>
        </form>
      )}

      {activeView === 'pending' && (
        <ReceiptList
          receipts={visibleReceipts}
          emptyTitle="Nenhum recebimento pendente"
          onApprove={onApprove}
          onRemove={onRemove}
        />
      )}
      {activeView === 'history' && (
        <ReceiptList
          receipts={visibleReceipts}
          emptyTitle="Nenhum recebimento no histórico"
          onApprove={onApprove}
          onRemove={onRemove}
        />
      )}
    </div>
  );
};

const StockTab = ({
  stock,
  onRefresh,
}: {
  stock: StockData[];
  onRefresh: () => void;
}) => {
  const [search, setSearch] = useState('');
  const [stockFilter, setStockFilter] = useState('all');
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(20);
  const normalizedSearch = normalizeSearch(search);
  const totalBalance = stock.reduce((total, item) => total + Number(item.saldo || 0), 0);
  const updatedItems = stock.filter(item => Number(item.delta_estoque || 0) !== 0).length;
  const latestUpdate = stock
    .map(item => item.updated_at ? new Date(item.updated_at).getTime() : 0)
    .filter(Boolean)
    .sort((a, b) => b - a)[0] || null;

  const visibleStock = stock.filter(item => {
    const balance = Number(item.saldo || 0);
    const delta = Number(item.delta_estoque || 0);
    const matchesSearch = !normalizedSearch || normalizeSearch(`${item.produto_id} ${item.nome}`).includes(normalizedSearch);
    const matchesFilter =
      stockFilter === 'all' ||
      (stockFilter === 'positive' && balance > 0) ||
      (stockFilter === 'empty' && balance <= 0) ||
      (stockFilter === 'changed' && delta !== 0);
    return matchesSearch && matchesFilter;
  }).sort((a, b) => Number(b.saldo || 0) - Number(a.saldo || 0));
  const totalPages = Math.ceil(visibleStock.length / itemsPerPage);
  const safeCurrentPage = Math.min(currentPage, totalPages || 1);
  const startIndex = (safeCurrentPage - 1) * itemsPerPage;
  const paginatedStock = visibleStock.slice(startIndex, startIndex + itemsPerPage);

  return (
    <div className="space-y-4">
      <div className="grid grid-cols-1 gap-3 md:grid-cols-4">
        <div className="rounded-xl border border-dark-border bg-dark-card p-4 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">SKUs</p>
          <p className="mt-2 text-2xl font-bold text-dark-text">{formatNumber(stock.length, 0)}</p>
        </div>
        <div className="rounded-xl border border-dark-border bg-dark-card p-4 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Saldo total</p>
          <p className="mt-2 text-2xl font-bold text-dark-text">{formatNumber(totalBalance, 0)} un.</p>
        </div>
        <div className="rounded-xl border border-dark-border bg-dark-card p-4 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Com delta</p>
          <p className="mt-2 text-2xl font-bold text-dark-text">{formatNumber(updatedItems, 0)}</p>
        </div>
        <div className="rounded-xl border border-dark-border bg-dark-card p-4 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Última atualização</p>
          <p className="mt-2 text-2xl font-bold text-dark-text">{latestUpdate ? formatDateTime(new Date(latestUpdate).toISOString()) : '-'}</p>
        </div>
      </div>

      <div className={`${panelClassName} p-4`}>
        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div>
            <h2 className="text-base font-bold text-dark-text">Estoque</h2>
            <p className="mt-1 text-sm font-semibold text-dark-muted">Saldo de produtos sincronizado pelo fluxo de estoque para Graphs.</p>
          </div>
          <div className="flex flex-col gap-2 sm:flex-row">
            <button
              type="button"
              onClick={() => exportCsv('estoque.csv', visibleStock.map(item => ({
                produto_id: item.produto_id,
                nome: item.nome,
                saldo: item.saldo,
                delta_estoque: item.delta_estoque,
                atualizado_em: item.updated_at || '',
              })))}
              className={buttonClassName}
            >
              <Download className="h-4 w-4" /> CSV
            </button>
            <button type="button" onClick={onRefresh} className={buttonClassName}>
              <RefreshCw className="h-4 w-4" /> Atualizar
            </button>
          </div>
        </div>

        <div className="mt-4 grid grid-cols-1 gap-3 lg:grid-cols-[1fr_220px]">
          <label className="relative">
            <Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
            <input
              value={search}
              onChange={(event) => {
                setSearch(event.target.value);
                setCurrentPage(1);
              }}
              className={`${inputClassName} pl-9`}
              placeholder="Buscar por SKU ou produto..."
            />
          </label>
          <select
            value={stockFilter}
            onChange={(event) => {
              setStockFilter(event.target.value);
              setCurrentPage(1);
            }}
            className={inputClassName}
          >
            <option value="all">Todos os saldos</option>
            <option value="positive">Com saldo</option>
            <option value="empty">Sem saldo</option>
            <option value="changed">Com delta</option>
          </select>
        </div>

        {visibleStock.length ? (
          <div className="mt-4 overflow-hidden rounded-xl border border-dark-border">
            <div className="hidden grid-cols-[140px_1fr_120px_120px_160px] border-b border-dark-border bg-dark-input/40 px-4 py-3 text-xs font-bold uppercase tracking-widest text-dark-muted md:grid">
              <span>SKU</span>
              <span>Produto</span>
              <span className="text-right">Saldo</span>
              <span className="text-right">Delta</span>
              <span className="text-right">Atualizado</span>
            </div>
            <div className="divide-y divide-dark-border">
              {paginatedStock.map(item => {
                const delta = Number(item.delta_estoque || 0);
                return (
                  <div key={item.produto_id} className="grid grid-cols-1 gap-2 bg-dark-card px-4 py-3 md:grid-cols-[140px_1fr_120px_120px_160px] md:items-center">
                    <p className="font-mono text-xs font-bold text-dark-muted">#{item.produto_id}</p>
                    <p className="text-sm font-bold text-dark-text">{item.nome}</p>
                    <p className="text-sm font-bold text-dark-text md:text-right">{formatNumber(Number(item.saldo || 0), 0)} un.</p>
                    <p className={`text-sm font-bold md:text-right ${delta > 0 ? 'text-emerald-300' : delta < 0 ? 'text-red-300' : 'text-dark-muted'}`}>
                      {delta > 0 ? '+' : ''}{formatNumber(delta, 0)}
                    </p>
                    <p className="text-xs font-semibold text-dark-muted md:text-right">{formatDateTime(item.updated_at || null)}</p>
                  </div>
                );
              })}
            </div>
            <PaginationControls
              totalItems={visibleStock.length}
              currentPage={safeCurrentPage}
              totalPages={totalPages}
              pageSize={itemsPerPage}
              pageSizeOptions={[20, 50, 100]}
              itemLabel="SKUs"
              pageSizeLabel="por página"
              startIndex={startIndex}
              endIndex={Math.min(startIndex + itemsPerPage, visibleStock.length)}
              onPageChange={setCurrentPage}
              onPageSizeChange={(pageSize) => {
                setItemsPerPage(pageSize);
                setCurrentPage(1);
              }}
              className="border-t border-dark-border px-4 py-3"
            />
          </div>
        ) : (
          <div className={emptyStateClassName}>
            <PackageSearch className="h-8 w-8 text-brand-primary" />
            <h3 className="text-base font-bold text-dark-text">{stock.length ? 'Nenhum SKU encontrado' : 'Nenhum estoque sincronizado'}</h3>
            <p className="text-sm font-semibold text-dark-muted">
              {stock.length ? 'Ajuste a busca ou o filtro.' : 'Quando o fluxo de estoque postar em /api/stock, os saldos aparecem aqui.'}
            </p>
          </div>
        )}
      </div>
    </div>
  );
};

const InventoryCountTab = ({
  lots,
  onAdjust,
  onRefresh,
}: {
  lots: SupplyLot[];
  onAdjust: (lotId: number, countedQuantity: number, reason: string) => Promise<void>;
  onRefresh: () => void;
}) => {
  const [search, setSearch] = useState('');
  const [adjustments, setAdjustments] = useState<Record<number, { countedQuantity: string; reason: string }>>({});
  const normalizedSearch = normalizeSearch(search);
  const visibleLots = lots.filter(lot => (
    !normalizedSearch || normalizeSearch(`${lot.product} ${lot.category} ${lot.supplier} ${lot.invoice} ${lot.id}`).includes(normalizedSearch)
  ));

  const updateAdjustment = (lotId: number, patch: Partial<{ countedQuantity: string; reason: string }>) => {
    setAdjustments(current => ({
      ...current,
      [lotId]: {
        countedQuantity: current[lotId]?.countedQuantity ?? '',
        reason: current[lotId]?.reason ?? '',
        ...patch,
      },
    }));
  };

  return (
    <div className="space-y-4">
      <button
        type="button"
        onClick={() => exportCsv('inventario-suprimentos.csv', visibleLots.map(lot => ({
          lote: lot.id,
          material: lot.product,
          categoria: lot.category,
          quantidade_sistema: lot.quantity,
          unidade: lot.unit,
          fornecedor: lot.supplier || 'Sem fornecedor',
        })))}
        className={buttonClassName}
      >
        <Download className="h-4 w-4" /> Exportar inventário CSV
      </button>
      <div className={`${panelClassName} p-5`}>
      <h2 className="text-base font-bold text-dark-text">Inventário físico</h2>
      <div className="mt-4 rounded-xl border border-dark-border bg-dark-input px-4 py-3 text-sm font-semibold text-dark-muted">
        Compare o estoque do sistema com a contagem física. O ajuste gera movimentação com justificativa.
      </div>
      <div className="mt-4 grid grid-cols-1 gap-3 md:grid-cols-[1fr_auto]">
        <input value={search} onChange={(event) => setSearch(event.target.value)} className={inputClassName} placeholder="Buscar item..." />
        <button type="button" onClick={onRefresh} className={buttonClassName}><RefreshCw className="h-4 w-4" /> Recarregar</button>
      </div>
      {visibleLots.length ? (
        <div className="mt-4 grid grid-cols-1 gap-3 md:grid-cols-2 xl:grid-cols-3">
          {visibleLots.map(lot => (
            <div key={lot.id} className="rounded-xl border border-dark-border bg-dark-input/35 p-4">
              <p className="text-sm font-bold text-dark-text">{lot.product}</p>
              <p className="mt-1 text-xs font-semibold text-dark-muted">{lot.category} · lote #{lot.id}</p>
              <p className="mt-3 text-xl font-bold text-dark-text">{formatNumber(lot.quantity)} {lot.unit}</p>
              <p className="mt-1 text-xs font-semibold text-dark-muted">{lot.supplier || 'Sem fornecedor'}</p>
              <div className="mt-4 grid grid-cols-1 gap-2">
                <label className="text-xs font-bold text-dark-muted">
                  Quantidade contada
                  <input
                    inputMode="decimal"
                    value={adjustments[lot.id]?.countedQuantity ?? ''}
                    onChange={(event) => updateAdjustment(lot.id, { countedQuantity: event.target.value })}
                    className={`${inputClassName} mt-1`}
                    placeholder={`${formatNumber(lot.quantity)} ${lot.unit}`}
                  />
                </label>
                <label className="text-xs font-bold text-dark-muted">
                  Justificativa
                  <input
                    value={adjustments[lot.id]?.reason ?? ''}
                    onChange={(event) => updateAdjustment(lot.id, { reason: event.target.value })}
                    className={`${inputClassName} mt-1`}
                    placeholder="ex: contagem física"
                  />
                </label>
                <button
                  type="button"
                  onClick={async () => {
                    const rawQuantity = adjustments[lot.id]?.countedQuantity ?? '';
                    if (!rawQuantity.trim()) return;
                    const nextQuantity = parseDecimal(rawQuantity);
                    const reason = adjustments[lot.id]?.reason.trim() ?? '';
                    await onAdjust(lot.id, nextQuantity, reason);
                    setAdjustments(current => ({ ...current, [lot.id]: { countedQuantity: '', reason: '' } }));
                  }}
                  className={buttonClassName}
                >
                  <ClipboardCheck className="h-4 w-4" />
                  Ajustar lote
                </button>
              </div>
            </div>
          ))}
        </div>
      ) : (
        <div className={emptyStateClassName}>
          <ClipboardCheck className="h-8 w-8 text-brand-primary" />
          <h3 className="text-base font-bold text-dark-text">{lots.length ? 'Nenhum lote encontrado' : 'Nenhum lote para inventariar'}</h3>
        </div>
      )}
    </div>
  </div>
  );
};

const movementLabels: Record<string, string> = {
  receipt: 'Entrada por recebimento',
  inventory_adjustment: 'Ajuste de inventário',
  production_exit: 'Saída para produção',
  reversal: 'Estorno',
};

const ProductionExitPanel = ({
  lots,
  onConsume,
}: {
  lots: SupplyLot[];
  onConsume: (lotId: number, quantity: number, productionOrderNumber: string, reason: string) => Promise<void>;
}) => {
  const [form, setForm] = useState({
    lotId: '',
    quantity: '',
    productionOrderNumber: '',
    reason: '',
  });

  const selectedLot = lots.find(lot => `${lot.id}` === form.lotId);

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const lotId = Number(form.lotId);
    const quantity = parseDecimal(form.quantity);
    if (!lotId || quantity <= 0) return;

    await onConsume(lotId, quantity, form.productionOrderNumber.trim(), form.reason.trim());
    setForm({ lotId: '', quantity: '', productionOrderNumber: '', reason: '' });
  };

  return (
    <form onSubmit={handleSubmit} className={`${panelClassName} p-5`}>
      <div className="flex flex-col gap-2 md:flex-row md:items-start md:justify-between">
        <div>
          <h2 className="text-base font-bold text-dark-text">Saída para produção</h2>
          <p className="mt-1 text-sm font-semibold text-dark-muted">Baixa material de um lote e registra movimentação ligada à OP.</p>
        </div>
        {selectedLot && (
          <span className="w-fit rounded-full border border-dark-border bg-dark-input px-2.5 py-1 text-xs font-bold text-dark-muted">
            Saldo: {formatNumber(selectedLot.quantity)} {selectedLot.unit}
          </span>
        )}
      </div>
      <div className="mt-4 grid grid-cols-1 gap-3 lg:grid-cols-[1.4fr_120px_160px_1fr_auto]">
        <label className="text-xs font-bold text-dark-muted">
          Lote
          <select value={form.lotId} onChange={(event) => setForm(current => ({ ...current, lotId: event.target.value }))} className={`${inputClassName} mt-1`}>
            <option value="">Selecione...</option>
            {lots.map(lot => (
              <option key={lot.id} value={lot.id}>
                #{lot.id} · {lot.product} · {formatNumber(lot.quantity)} {lot.unit}
              </option>
            ))}
          </select>
        </label>
        <label className="text-xs font-bold text-dark-muted">
          Quantidade
          <input inputMode="decimal" value={form.quantity} onChange={(event) => setForm(current => ({ ...current, quantity: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="kg" />
        </label>
        <label className="text-xs font-bold text-dark-muted">
          OP
          <input value={form.productionOrderNumber} onChange={(event) => setForm(current => ({ ...current, productionOrderNumber: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: OP-123" />
        </label>
        <label className="text-xs font-bold text-dark-muted">
          Motivo
          <input value={form.reason} onChange={(event) => setForm(current => ({ ...current, reason: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: corte BLCS" />
        </label>
        <button type="submit" className={`${buttonClassName} mt-5`}>
          <Repeat2 className="h-4 w-4" />
          Baixar
        </button>
      </div>
    </form>
  );
};

const MovementsTab = ({
  lots,
  movements,
  onConsume,
}: {
  lots: SupplyLot[];
  movements: SupplyMovement[];
  onConsume: (lotId: number, quantity: number, productionOrderNumber: string, reason: string) => Promise<void>;
}) => {
  const [search, setSearch] = useState('');
  const [type, setType] = useState('all');
  const movementTypes = Array.from(new Set(movements.map(movement => movement.type))).sort();
  const normalizedSearch = normalizeSearch(search);
  const visibleMovements = movements.filter(movement => {
    const matchesSearch = !normalizedSearch || normalizeSearch(`${movement.product} ${movement.category} ${movement.reason} ${movement.lotId || ''}`).includes(normalizedSearch);
    const matchesType = type === 'all' || movement.type === type;
    return matchesSearch && matchesType;
  });

  return (
    <div className="space-y-4">
      <ProductionExitPanel lots={lots} onConsume={onConsume} />
      <button
        type="button"
        onClick={() => exportCsv('movimentacoes-suprimentos.csv', visibleMovements.map(movement => ({
          id: movement.id,
          data: movement.createdAt,
          tipo: movementLabels[movement.type] || movement.type,
          material: movement.product,
          categoria: movement.category,
          quantidade: movement.quantity,
          unidade: movement.unit,
          lote: movement.lotId,
          motivo: movement.reason,
        })))}
        className={buttonClassName}
      >
        <Download className="h-4 w-4" /> Exportar movimentações CSV
      </button>
      <div className={`${panelClassName} p-4`}>
      <div className="grid grid-cols-1 gap-3 md:grid-cols-[1fr_220px]">
        <label className="relative">
          <Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
          <input value={search} onChange={(event) => setSearch(event.target.value)} className={`${inputClassName} pl-9`} placeholder="Buscar lote, tipo ou fornecedor..." />
        </label>
        <select value={type} onChange={(event) => setType(event.target.value)} className={inputClassName}>
          <option value="all">Todos os tipos</option>
          {movementTypes.map(item => <option key={item} value={item}>{movementLabels[item] || item}</option>)}
        </select>
      </div>
      {visibleMovements.length ? (
        <div className="mt-4 overflow-hidden rounded-xl border border-dark-border">
          <div className="hidden grid-cols-[170px_1fr_140px_140px] border-b border-dark-border bg-dark-input/40 px-4 py-3 text-xs font-bold uppercase tracking-widest text-dark-muted md:grid">
            <span>Data</span>
            <span>Movimento</span>
            <span>Quantidade</span>
            <span>Lote</span>
          </div>
          <div className="divide-y divide-dark-border">
            {visibleMovements.map(movement => (
              <div key={movement.id} className="grid grid-cols-1 gap-2 bg-dark-card px-4 py-3 md:grid-cols-[170px_1fr_140px_140px] md:items-center">
                <p className="text-sm font-semibold text-dark-muted">{formatDateTime(movement.createdAt)}</p>
                <div>
                  <p className="text-sm font-bold text-dark-text">{movementLabels[movement.type] || movement.type}</p>
                  <p className="text-xs font-semibold text-dark-muted">{movement.product} · {movement.reason}</p>
                </div>
                <p className="text-sm font-bold text-dark-text">{formatNumber(movement.quantity)} {movement.unit}</p>
                <p className="text-xs font-bold text-dark-muted">{movement.lotId ? `#${movement.lotId}` : '-'}</p>
              </div>
            ))}
          </div>
        </div>
      ) : (
        <div className={emptyStateClassName}>
          <Repeat2 className="h-8 w-8 text-brand-primary" />
          <h3 className="text-base font-bold text-dark-text">{movements.length ? 'Nenhuma movimentação encontrada' : 'Nenhuma movimentação ainda'}</h3>
        </div>
      )}
    </div>
  </div>
  );
};

const InventoryScreen = () => {
  const [activeTab, setActiveTab] = useState<InventoryTab>('dashboard');
  const [summary, setSummary] = useState<SupplySummary>(emptySupplySummary);
  const [stockSnapshot, setStockSnapshot] = useState<StockData[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [isBusy, setIsBusy] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  const loadInventoryData = async () => {
    setErrorMessage('');
    const [nextSummary, nextStockSnapshot] = await Promise.all([
      fetchSupplySummary(),
      fetchStock(),
    ]);
    setSummary(nextSummary);
    setStockSnapshot(nextStockSnapshot);
  };

  const loadSummary = async () => {
    setErrorMessage('');
    const nextSummary = await fetchSupplySummary();
    setSummary(nextSummary);
  };

  const loadStockSnapshot = async () => {
    setErrorMessage('');
    setStockSnapshot(await fetchStock());
  };

  useEffect(() => {
    let isMounted = true;

    const load = async () => {
      setIsLoading(true);
      try {
        const [nextSummary, nextStockSnapshot] = await Promise.all([
          fetchSupplySummary(),
          fetchStock(),
        ]);
        if (isMounted) {
          setSummary(nextSummary);
          setStockSnapshot(nextStockSnapshot);
        }
      } finally {
        if (isMounted) setIsLoading(false);
      }
    };

    load();

    return () => {
      isMounted = false;
    };
  }, []);

  const runSupplyAction = async (action: () => Promise<void>) => {
    setIsBusy(true);
    setErrorMessage('');
    try {
      await action();
      await loadInventoryData();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Não foi possível atualizar suprimentos.');
    } finally {
      setIsBusy(false);
    }
  };

  return (
    <div className={pageClassName}>
      <Header title="Controle de Estoque" subtitle="Saldo, lotes, entradas e inventário." backTo="/supplies" />
      <div className="flex flex-wrap gap-2">
        {inventoryTabs.map(tab => (
          <button
            key={tab.id}
            type="button"
            onClick={() => setActiveTab(tab.id)}
            className={`inline-flex h-10 items-center justify-center gap-2 rounded-lg px-3 text-sm font-bold transition-colors cursor-pointer ${
              activeTab === tab.id ? 'bg-brand-primary text-brand-contrast' : 'bg-dark-input text-dark-text hover:bg-dark-card'
            }`}
          >
            <tab.icon className="h-4 w-4" />
            {tab.name}
          </button>
        ))}
      </div>
      {errorMessage && (
        <div className="rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm font-bold text-red-300">
          {errorMessage}
        </div>
      )}
      {isLoading ? (
        <div className={`${panelClassName} p-5 text-sm font-bold text-dark-muted`}>Carregando estoque...</div>
      ) : (
        <>
          {activeTab === 'dashboard' && <InventoryDashboard summary={summary} onNewReceipt={() => setActiveTab('receipts')} />}
          {activeTab === 'stock' && <StockTab stock={stockSnapshot} onRefresh={loadStockSnapshot} />}
          {activeTab === 'balance' && <BalanceTab summary={summary} onRefresh={loadSummary} />}
          {activeTab === 'receipts' && (
            <ReceiptsTab
              receipts={summary.receipts}
              isBusy={isBusy}
              onCreate={(payload) => runSupplyAction(async () => {
                await createSupplyReceipt(payload);
              })}
              onApprove={(receiptId) => runSupplyAction(async () => {
                await approveSupplyReceipt(receiptId);
              })}
              onRemove={(receiptId) => runSupplyAction(async () => {
                await deleteSupplyReceipt(receiptId);
              })}
            />
          )}
          {activeTab === 'inventory' && (
            <InventoryCountTab
              lots={summary.lots}
              onRefresh={loadSummary}
              onAdjust={(lotId, countedQuantity, reason) => runSupplyAction(async () => {
                await adjustSupplyLotInventory(lotId, { countedQuantity, reason });
              })}
            />
          )}
          {activeTab === 'movements' && (
            <MovementsTab
              lots={summary.lots}
              movements={summary.movements}
              onConsume={(lotId, quantity, productionOrderNumber, reason) => runSupplyAction(async () => {
                await consumeSupplyLotForProduction(lotId, { quantity, productionOrderNumber, reason });
              })}
            />
          )}
        </>
      )}
    </div>
  );
};

const FabricPlanningScreen = () => {
  const [plans, setPlans] = useState<SupplyFabricPlan[]>([]);
  const [form, setForm] = useState({
    material: '',
    color: '',
    quantityKg: '',
    supplier: '',
    priority: 'Normal',
  });
  const [isLoading, setIsLoading] = useState(true);
  const [isBusy, setIsBusy] = useState(false);
  const [errorMessage, setErrorMessage] = useState('');

  const totalKg = plans.reduce((total, plan) => total + plan.quantityKg, 0);

  const loadPlans = async () => {
    setErrorMessage('');
    const summary = await fetchSupplySummary();
    setPlans(summary.fabricPlans);
  };

  useEffect(() => {
    let isMounted = true;

    const load = async () => {
      setIsLoading(true);
      try {
        const summary = await fetchSupplySummary();
        if (isMounted) setPlans(summary.fabricPlans);
      } finally {
        if (isMounted) setIsLoading(false);
      }
    };

    load();

    return () => {
      isMounted = false;
    };
  }, []);

  const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    const material = form.material.trim();
    const quantityKg = parseDecimal(form.quantityKg);
    if (!material || quantityKg <= 0) return;

    setIsBusy(true);
    setErrorMessage('');
    try {
      await createSupplyFabricPlan({
        material,
        color: form.color.trim() || 'Todas as cores',
        quantityKg,
        supplier: form.supplier.trim() || 'Sem fornecedor',
        priority: form.priority,
      });
      await loadPlans();
      setForm({ material: '', color: '', quantityKg: '', supplier: '', priority: 'Normal' });
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Não foi possível salvar o plano de malha.');
    } finally {
      setIsBusy(false);
    }
  };

  const removePlan = async (planId: number) => {
    setIsBusy(true);
    setErrorMessage('');
    try {
      await deleteSupplyFabricPlan(planId);
      await loadPlans();
    } catch (error) {
      setErrorMessage(error instanceof Error ? error.message : 'Não foi possível remover o plano de malha.');
    } finally {
      setIsBusy(false);
    }
  };

  return (
    <div className={pageClassName}>
      <Header title="Planejamento de Malha" subtitle="Fila de matéria-prima para compra, recebimento e abastecimento do corte." backTo="/supplies" />
      {errorMessage && (
        <div className="rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm font-bold text-red-300">
          {errorMessage}
        </div>
      )}
      <div className="grid grid-cols-1 gap-4 md:grid-cols-3">
        <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Planos ativos</p>
          <p className="mt-2 text-3xl font-bold text-dark-text">{plans.length}</p>
        </div>
        <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Kg planejado</p>
          <p className="mt-2 text-3xl font-bold text-dark-text">{formatNumber(totalKg)} kg</p>
        </div>
        <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
          <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">Críticos</p>
          <p className="mt-2 text-3xl font-bold text-dark-text">{plans.filter(plan => plan.priority === 'Crítico').length}</p>
        </div>
      </div>

      <div className="grid grid-cols-1 items-stretch gap-6 xl:grid-cols-[1fr_420px]">
        <div className={`${panelClassName} flex flex-col overflow-hidden`}>
          <div className="border-b border-dark-border p-5">
            <h2 className="text-base font-bold text-dark-text">Planos de malha</h2>
            <p className="mt-1 text-sm font-semibold text-dark-muted">Itens planejados para compra ou recebimento.</p>
          </div>
          {isLoading ? (
            <div className={`${emptyStateClassName} min-h-[220px] flex-1`}>
              <Ruler className="h-8 w-8 text-brand-primary" />
              <h3 className="text-base font-bold text-dark-text">Carregando planos...</h3>
            </div>
          ) : plans.length ? (
            <div className="divide-y divide-dark-border">
              {plans.map(plan => (
                <div key={plan.id} className="grid grid-cols-1 gap-3 p-4 md:grid-cols-[1.4fr_1fr_100px_100px_44px] md:items-center">
                  <div>
                    <p className="font-bold text-dark-text">{plan.material}</p>
                    <p className="text-xs font-semibold text-dark-muted">{plan.color}</p>
                  </div>
                  <p className="text-sm font-semibold text-dark-muted">{plan.supplier}</p>
                  <p className="text-sm font-bold text-dark-text">{formatNumber(plan.quantityKg)} kg</p>
                  <span className="w-fit rounded-full border border-dark-border bg-dark-input px-2.5 py-1 text-xs font-bold text-dark-text">{plan.priority}</span>
                  <button
                    type="button"
                    title="Remover plano"
                    aria-label={`Remover plano ${plan.material}`}
                    disabled={isBusy}
                    onClick={() => removePlan(plan.id)}
                    className="inline-flex h-10 w-10 items-center justify-center rounded-lg text-red-400 transition-colors hover:bg-red-500/10 hover:text-red-300 disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer"
                  >
                    <Trash2 className="h-4 w-4" />
                  </button>
                </div>
              ))}
            </div>
          ) : (
            <div className={`${emptyStateClassName} flex-1`}>
              <Ruler className="h-8 w-8 text-brand-primary" />
              <h3 className="text-base font-bold text-dark-text">Nenhum plano de malha cadastrado</h3>
              <p className="text-sm font-semibold text-dark-muted">Cadastre o primeiro plano no formulário ao lado.</p>
            </div>
          )}
        </div>

        <form onSubmit={handleSubmit} className={`${panelClassName} p-5`}>
          <h2 className="text-base font-bold text-dark-text">Novo plano de malha</h2>
          <div className="mt-4 grid grid-cols-1 gap-3">
            <label className="text-xs font-bold text-dark-muted">
              Malha / tecido
              <input value={form.material} onChange={(event) => setForm(current => ({ ...current, material: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: Meia malha 30.1" />
            </label>
            <label className="text-xs font-bold text-dark-muted">
              Cor
              <input value={form.color} onChange={(event) => setForm(current => ({ ...current, color: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="Todas as cores" />
            </label>
            <div className="grid grid-cols-1 gap-3 sm:grid-cols-2">
              <label className="text-xs font-bold text-dark-muted">
                Quantidade kg
                <input inputMode="decimal" value={form.quantityKg} onChange={(event) => setForm(current => ({ ...current, quantityKg: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="ex: 180" />
              </label>
              <label className="text-xs font-bold text-dark-muted">
                Prioridade
                <select value={form.priority} onChange={(event) => setForm(current => ({ ...current, priority: event.target.value }))} className={`${inputClassName} mt-1`}>
                  <option>Normal</option>
                  <option>Atenção</option>
                  <option>Crítico</option>
                </select>
              </label>
            </div>
            <label className="text-xs font-bold text-dark-muted">
              Fornecedor
              <input value={form.supplier} onChange={(event) => setForm(current => ({ ...current, supplier: event.target.value }))} className={`${inputClassName} mt-1`} placeholder="Opcional" />
            </label>
            <button type="submit" disabled={isBusy} className="mt-2 inline-flex h-11 items-center justify-center gap-2 rounded-lg bg-brand-primary px-4 text-sm font-bold text-brand-contrast transition-opacity hover:opacity-90 disabled:cursor-not-allowed disabled:opacity-60 cursor-pointer">
              <Save className="h-4 w-4" />
              {isBusy ? 'Salvando...' : 'Salvar plano'}
            </button>
          </div>
        </form>
      </div>
    </div>
  );
};

const purchaseStatusLabels: Record<SupplyPurchaseNeed['status'], string> = {
  critical: 'Sem estoque',
  attention: 'Comprar',
  ok: 'Coberto',
};

const getNeedUnit = (need: SupplyPurchaseNeed) => need.unit || 'kg';

const formatNeedQuantity = (need: SupplyPurchaseNeed, value: number) => (
  `${formatNumber(value)} ${getNeedUnit(need)}`
);

const summarizePurchaseNeeds = (needs: SupplyPurchaseNeed[]) => {
  const totalsByUnit = needs.reduce<Record<string, number>>((totals, need) => {
    if (need.purchaseKg <= 0) return totals;
    const unit = getNeedUnit(need);
    totals[unit] = (totals[unit] || 0) + need.purchaseKg;
    return totals;
  }, {});

  const summaries = Object.entries(totalsByUnit).map(([unit, total]) => `${formatNumber(total)} ${unit}`);
  return summaries.length ? summaries.join(' + ') : '0 kg';
};

const PurchaseNeedsScreen = () => {
  const [summary, setSummary] = useState<SupplySummary>(emptySupplySummary);
  const [isLoading, setIsLoading] = useState(true);
  const [search, setSearch] = useState('');
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(10);

  const loadSummary = async () => {
    const nextSummary = await fetchSupplySummary();
    setSummary(nextSummary);
  };

  useEffect(() => {
    let isMounted = true;

    const load = async () => {
      setIsLoading(true);
      try {
        const nextSummary = await fetchSupplySummary();
        if (isMounted) setSummary(nextSummary);
      } finally {
        if (isMounted) setIsLoading(false);
      }
    };

    load();

    return () => {
      isMounted = false;
    };
  }, []);

  const normalizedSearch = normalizeSearch(search);
  const visibleNeeds = summary.purchaseNeeds.filter(need => (
    !normalizedSearch || normalizeSearch(`${need.material} ${need.suppliers.join(' ')} ${need.colors.join(' ')}`).includes(normalizedSearch)
  ));
  const totalPages = Math.ceil(visibleNeeds.length / itemsPerPage);
  const safeCurrentPage = Math.min(currentPage, totalPages || 1);
  const startIndex = (safeCurrentPage - 1) * itemsPerPage;
  const paginatedNeeds = visibleNeeds.slice(startIndex, startIndex + itemsPerPage);
  const purchaseItemCount = summary.purchaseNeeds.filter(need => need.purchaseKg > 0).length;
  const suggestedPurchaseSummary = summarizePurchaseNeeds(summary.purchaseNeeds);
  const pendingSupplierCount = new Set(summary.purchaseNeeds.flatMap(need => need.suppliers)).size;
  const missingReferenceCount = summary.purchaseNeeds.filter(need => need.missingReference).length;

  return (
    <div className={pageClassName}>
      <Header title="Necessidade de Compra" subtitle="Materiais abaixo do mínimo e necessidade projetada para compra." backTo="/supplies" />
      <div className="grid grid-cols-1 gap-4 md:grid-cols-4">
        {[
          { label: 'Itens a comprar', value: `${purchaseItemCount}` },
          { label: 'Compra sugerida', value: suggestedPurchaseSummary },
          { label: 'Fornecedores', value: `${pendingSupplierCount}` },
          { label: 'Sem referência', value: `${missingReferenceCount}` },
        ].map(stat => (
          <div key={stat.label} className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
            <p className="text-xs font-bold uppercase tracking-widest text-dark-muted">{stat.label}</p>
            <p className="mt-2 text-3xl font-bold text-dark-text">{stat.value}</p>
          </div>
        ))}
      </div>
      <div className={`${panelClassName} p-5`}>
        <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
          <div>
            <h2 className="text-base font-bold text-dark-text">Necessidade por material</h2>
            <p className="mt-1 text-sm font-semibold text-dark-muted">Planejado - estoque aprovado - recebimentos pendentes.</p>
          </div>
          <div className="flex flex-wrap gap-2">
            <button type="button" onClick={loadSummary} className={buttonClassName}><RefreshCw className="h-4 w-4" /> Atualizar</button>
            <button
              type="button"
              onClick={() => exportCsv('necessidade-compra.csv', visibleNeeds.map(need => ({
                material: need.material,
                planejado_kg: need.plannedKg,
                estoque_kg: need.stockKg,
                pendente_kg: need.pendingKg,
                comprar_kg: need.purchaseKg,
                unidade: getNeedUnit(need),
                prioridade: need.priority,
                cobertura: need.missingReference ? 'Sem referência de consumo' : purchaseStatusLabels[need.status],
                fornecedores: need.suppliers.join(' | '),
                cores: need.colors.join(' | '),
                produtos: (need.products || []).map(product => `${product.productId} ${product.name}`).join(' | '),
              })))}
              className={buttonClassName}
            >
              <Download className="h-4 w-4" /> Exportar CSV
            </button>
          </div>
        </div>
        <label className="relative mt-4 block">
          <Search className="pointer-events-none absolute left-3 top-3 h-4 w-4 text-dark-muted" />
          <input
            value={search}
            onChange={(event) => {
              setSearch(event.target.value);
              setCurrentPage(1);
            }}
            className={`${inputClassName} pl-9`}
            placeholder="Buscar por material, fornecedor ou cor..."
          />
        </label>
        {isLoading ? (
          <div className={emptyStateClassName}>
            <BarChart3 className="h-8 w-8 text-brand-primary" />
            <h3 className="text-base font-bold text-dark-text">Calculando necessidade...</h3>
          </div>
        ) : visibleNeeds.length ? (
          <div className="mt-4 overflow-hidden rounded-xl border border-dark-border">
            <div className="overflow-x-auto">
              <table className="w-full min-w-[920px] table-fixed border-collapse">
                <colgroup>
                  <col />
                  <col className="w-[120px]" />
                  <col className="w-[120px]" />
                  <col className="w-[120px]" />
                  <col className="w-[120px]" />
                  <col className="w-[150px]" />
                </colgroup>
                <thead className="border-b border-dark-border bg-dark-input/40 text-xs font-bold uppercase tracking-widest text-dark-muted">
                  <tr>
                    <th scope="col" className="px-4 py-3 text-left">Material</th>
                    <th scope="col" className="px-4 py-3 text-right">Planejado</th>
                    <th scope="col" className="px-4 py-3 text-right">Estoque</th>
                    <th scope="col" className="px-4 py-3 text-right">Pendente</th>
                    <th scope="col" className="px-4 py-3 text-right">Comprar</th>
                    <th scope="col" className="px-4 py-3 text-left">Cobertura</th>
                  </tr>
                </thead>
                <tbody className="divide-y divide-dark-border bg-dark-card">
              {paginatedNeeds.map(need => {
                const referenceProduct = need.products?.[0];
                return (
                  <tr key={need.material}>
                    <td className="px-4 py-4 align-middle">
                      <div className="min-w-0">
                      <p className="text-sm font-bold text-dark-text">{need.material}</p>
                      <div className="mt-1 flex flex-wrap items-center gap-2">
                        <p className="text-xs font-semibold text-dark-muted">
                          {need.missingReference
                            ? 'Cadastre produto/material em Cadastros > Referência de Consumo'
                            : `${(need.colors.length ? need.colors.join(', ') : 'Todas as cores')} · ${(need.suppliers.length ? need.suppliers.join(', ') : 'Sem fornecedor')}`}
                        </p>
                        {need.missingReference && referenceProduct ? (
                          <RouterLink
                            to={buildConsumptionReferencePath({ sku: referenceProduct.productId, name: referenceProduct.name })}
                            className="inline-flex h-7 w-7 items-center justify-center rounded-lg bg-dark-input text-dark-text transition-colors hover:bg-dark-border"
                            title={`Cadastrar referência do SKU ${referenceProduct.productId}`}
                            aria-label={`Cadastrar referência do SKU ${referenceProduct.productId}`}
                          >
                            <Pencil className="h-3.5 w-3.5" />
                          </RouterLink>
                        ) : null}
                      </div>
                      {need.products?.length ? (
                        <p className="mt-1 text-xs font-semibold text-dark-muted">
                          {need.products.slice(0, 2).map(product => product.productId).join(', ')}
                          {need.products.length > 2 ? ` +${need.products.length - 2}` : ''}
                        </p>
                      ) : null}
                      </div>
                    </td>
                    <td className="px-4 py-4 text-right align-middle text-sm font-bold text-dark-text">{formatNeedQuantity(need, need.plannedKg)}</td>
                    <td className="px-4 py-4 text-right align-middle text-sm font-bold text-dark-text">{formatNeedQuantity(need, need.stockKg)}</td>
                    <td className="px-4 py-4 text-right align-middle text-sm font-bold text-dark-text">{formatNeedQuantity(need, need.pendingKg)}</td>
                    <td className={`px-4 py-4 text-right align-middle text-sm font-bold ${need.purchaseKg > 0 ? 'text-amber-300' : 'text-emerald-300'}`}>{formatNeedQuantity(need, need.purchaseKg)}</td>
                    <td className="px-4 py-4 align-middle">
                      <span className={`inline-flex whitespace-nowrap rounded-full border px-2.5 py-1 text-xs font-bold ${
                      need.missingReference
                        ? 'border-red-400/30 bg-red-400/10 text-red-300'
                        : need.status === 'critical'
                        ? 'border-red-400/30 bg-red-400/10 text-red-300'
                        : need.status === 'attention'
                          ? 'border-amber-400/30 bg-amber-400/10 text-amber-300'
                          : 'border-emerald-400/30 bg-emerald-400/10 text-emerald-300'
                    }`}>
                      {need.missingReference ? 'Sem referência' : purchaseStatusLabels[need.status]}
                    </span>
                    </td>
                  </tr>
                );
              })}
                </tbody>
              </table>
            </div>
            <PaginationControls
              totalItems={visibleNeeds.length}
              currentPage={safeCurrentPage}
              totalPages={totalPages}
              pageSize={itemsPerPage}
              pageSizeOptions={[10, 20, 50, 100]}
              itemLabel="materiais"
              pageSizeLabel="itens por página"
              startIndex={startIndex}
              endIndex={Math.min(startIndex + itemsPerPage, visibleNeeds.length)}
              onPageChange={setCurrentPage}
              onPageSizeChange={(pageSize) => {
                setItemsPerPage(pageSize);
                setCurrentPage(1);
              }}
              className="border-t border-dark-border px-4 py-3"
            />
          </div>
        ) : (
          <div className={emptyStateClassName}>
            <BarChart3 className="h-8 w-8 text-brand-primary" />
            <h3 className="text-base font-bold text-dark-text">{summary.purchaseNeeds.length ? 'Nenhuma necessidade encontrada' : 'Nenhuma necessidade de compra'}</h3>
            <p className="text-sm font-semibold text-dark-muted">{summary.purchaseNeeds.length ? 'Ajuste a busca.' : 'Cadastre planos de malha para gerar demanda e aprove recebimentos para abater estoque.'}</p>
          </div>
        )}
      </div>
    </div>
  );
};

const Supplies = () => {
  const { section } = useParams<{ section?: string }>();

  if (!section) return <SuppliesHub />;
  if (section === 'current-planning') return <DemandPlanningScreen />;
  if (section === 'inventory') return <InventoryScreen />;
  if (section === 'fabric-planning') return <FabricPlanningScreen />;
  if (section === 'purchase-needs') return <PurchaseNeedsScreen />;

  return <Navigate to="/supplies" replace />;
};

export default Supplies;
