import { useEffect, useMemo, useState } from 'react';
import { Link, useOutletContext, useParams } from 'react-router-dom';
import { DollarSign, Package, Palette, Ruler, TrendingDown, TrendingUp, Warehouse } from 'lucide-react';
import BackButton from '../components/BackButton';
import DateRangePicker from '../components/DateRangePicker';
import PaginationControls from '../components/PaginationControls';
import RefreshStatus from '../components/RefreshStatus';
import { fetchProductAnalytics } from '../dataService';
import { decodeProductGroupKey, normalizeProductText, parseProductName } from '../productParsing';
import type { DateRange, ProductAnalyticsItem } from '../types';

type VariantRow = ProductAnalyticsItem & {
  color: string;
  size: string;
  dailySales: number;
  daysOfCover: number | null;
};

type BreakdownRow = {
  label: string;
  quantitySold: number;
  revenue: number;
  stock: number;
  skuCount: number;
};

const BREAKDOWN_LIMIT = 12;

const COLOR_SWATCHES: Array<{ pattern: string; color: string }> = [
  { pattern: 'preto', color: '#171717' },
  { pattern: 'branco', color: '#f8fafc' },
  { pattern: 'bege', color: '#d7bf9a' },
  { pattern: 'café', color: '#79553d' },
  { pattern: 'cafe', color: '#79553d' },
  { pattern: 'perola', color: '#e7dfcf' },
  { pattern: 'pérola', color: '#e7dfcf' },
  { pattern: 'marinho', color: '#172554' },
  { pattern: 'bordo', color: '#6b1226' },
  { pattern: 'bordô', color: '#6b1226' },
  { pattern: 'verde', color: '#166534' },
  { pattern: 'rosa', color: '#f0a6bf' },
  { pattern: 'cinza', color: '#8f8f8f' },
  { pattern: 'vermelho', color: '#b91c1c' },
  { pattern: 'grafite', color: '#3f3f46' },
  { pattern: 'azul', color: '#2563eb' }
];

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 formatNumber = (value: number, maximumFractionDigits = 0) => (
  new Intl.NumberFormat('pt-BR', { maximumFractionDigits }).format(value)
);

const formatCurrency = (value: number) => (
  new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' }).format(value)
);

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

const getSwatchColor = (label: string) => {
  const normalizedLabel = label.normalize('NFD').replace(/\p{Diacritic}/gu, '').toLowerCase();
  return COLOR_SWATCHES.find(item => normalizedLabel.includes(item.pattern.normalize('NFD').replace(/\p{Diacritic}/gu, '')))?.color || '#64748b';
};

const getBarColor = (label: string) => {
  const color = getSwatchColor(label);
  return `color-mix(in srgb, ${color} 74%, var(--color-dark-text) 26%)`;
};

const ColorSwatch = ({ label, className = 'h-2.5 w-2.5' }: { label: string; className?: string }) => (
  <span
    className={`${className} shrink-0 rounded-sm`}
    style={{
      backgroundColor: getSwatchColor(label),
      boxShadow: '0 0 0 1px var(--color-dark-card), 0 0 0 2px var(--color-dark-border)'
    }}
  />
);

const buildBreakdown = (rows: VariantRow[], field: 'color' | 'size') => {
  const totals = new Map<string, BreakdownRow>();

  rows.forEach(row => {
    const label = row[field] || (field === 'color' ? 'Sem cor' : 'Sem tamanho');
    const current = totals.get(label) || { label, quantitySold: 0, revenue: 0, stock: 0, skuCount: 0 };
    totals.set(label, {
      label,
      quantitySold: current.quantitySold + row.quantitySold,
      revenue: current.revenue + row.revenue,
      stock: current.stock + row.stock,
      skuCount: current.skuCount + 1
    });
  });

  return [...totals.values()].sort((a, b) => b.quantitySold - a.quantitySold);
};

const BreakdownPanel = ({
  title,
  subtitle,
  rows,
  type
}: {
  title: string;
  subtitle: string;
  rows: BreakdownRow[];
  type: 'color' | 'size';
}) => {
  const maxSold = Math.max(...rows.map(row => row.quantitySold), 0);
  const visibleRows = rows.slice(0, BREAKDOWN_LIMIT);
  const hiddenCount = Math.max(0, rows.length - visibleRows.length);

  return (
    <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
      <div className="mb-5 flex items-start justify-between gap-4">
        <div>
          <h3 className="text-base font-bold text-dark-text">{title}</h3>
          <p className="mt-1 text-sm font-medium text-dark-muted">{subtitle}</p>
        </div>
        {type === 'color' ? (
          <Palette className="h-5 w-5 text-brand-primary" />
        ) : (
          <Ruler className="h-5 w-5 text-brand-primary" />
        )}
      </div>

      {rows.length === 0 ? (
        <div className="flex h-32 items-center justify-center text-sm font-semibold text-dark-muted">
          Sem dados para este grupo.
        </div>
      ) : (
        <div className="space-y-3">
          {visibleRows.map(row => {
            const width = maxSold ? Math.max(4, (row.quantitySold / maxSold) * 100) : 0;
            const barColor = type === 'color' ? getBarColor(row.label) : '#25c2ff';

            return (
              <div key={row.label} className="grid grid-cols-[minmax(7.5rem,9rem)_1fr_6rem] items-center gap-3">
                <div className="flex min-w-0 items-center gap-2">
                  {type === 'color' ? <ColorSwatch label={row.label} /> : <span className="h-2.5 w-2.5 shrink-0 rounded-sm bg-sky-400" />}
                  <span className="truncate text-xs font-bold text-dark-text" title={row.label}>
                    {type === 'size' && row.label !== 'Sem tamanho' ? `Tam. ${row.label}` : row.label}
                  </span>
                </div>
                <div className="h-3 overflow-hidden rounded-full border border-dark-border bg-dark-input">
                  <div
                    className="h-full rounded-full"
                    style={{ width: `${width}%`, backgroundColor: barColor }}
                  />
                </div>
                <div className="text-right text-xs">
                  <div className="font-bold text-dark-text">{formatNumber(row.quantitySold)} un.</div>
                  <div className="text-[10px] font-semibold text-dark-muted">{row.skuCount} SKUs</div>
                </div>
              </div>
            );
          })}
          {hiddenCount > 0 && (
            <div className="border-t border-dark-border pt-3 text-xs font-semibold text-dark-muted">
              +{formatNumber(hiddenCount)} itens fora do top {BREAKDOWN_LIMIT}
            </div>
          )}
        </div>
      )}
    </div>
  );
};

const ProductGroupDetailsSkeleton = () => (
  <div className="space-y-6" aria-label="Carregando grupo de produtos">
    <div className="flex flex-col gap-4">
      <div className="skeleton h-4 w-20" />
      <div className="flex items-center gap-4">
        <div className="skeleton h-16 w-16 rounded-2xl" />
        <div className="w-full max-w-xl">
          <div className="skeleton h-3 w-24" />
          <div className="skeleton mt-3 h-7 w-full" />
        </div>
      </div>
    </div>
    <div className="grid grid-cols-1 gap-4 md:grid-cols-4">
      {[0, 1, 2, 3].map(item => (
        <div key={`group-kpi-skeleton-${item}`} className="skeleton h-28 rounded-2xl" />
      ))}
    </div>
    <div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
      <div className="skeleton h-80 rounded-2xl" />
      <div className="skeleton h-80 rounded-2xl" />
    </div>
  </div>
);

const ProductGroupDetails = () => {
  const { groupKey } = useParams<{ groupKey: string }>();
  const { dateRange, setDateRange } = useOutletContext<{
    dateRange: DateRange,
    setDateRange: (range: DateRange) => void
  }>();
  const [products, setProducts] = useState<ProductAnalyticsItem[]>([]);
  const [isLoading, setIsLoading] = useState(true);
  const [currentPage, setCurrentPage] = useState(1);
  const [itemsPerPage, setItemsPerPage] = useState(20);

  const groupName = useMemo(() => {
    if (!groupKey) return '';

    try {
      return decodeProductGroupKey(groupKey);
    } catch {
      return '';
    }
  }, [groupKey]);

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

    const loadProducts = async () => {
      setIsLoading(true);
      const data = await fetchProductAnalytics(dateRange);

      if (isMounted) {
        setProducts(data);
        setIsLoading(false);
      }
    };

    void loadProducts();

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

  const groupRows = useMemo<VariantRow[]>(() => {
    const rangeDays = getRangeDays(dateRange);
    const normalizedGroupName = normalizeProductText(groupName).toLowerCase();

    return products
      .map(product => {
        const metadata = parseProductName(product.name);
        const dailySales = product.quantitySold / rangeDays;

        return {
          ...product,
          color: metadata.color,
          size: metadata.size,
          baseName: metadata.baseName,
          dailySales,
          daysOfCover: dailySales > 0 ? product.stock / dailySales : null
        };
      })
      .filter(product => normalizeProductText(product.baseName).toLowerCase() === normalizedGroupName)
      .sort((a, b) => b.quantitySold - a.quantitySold);
  }, [dateRange, groupName, products]);

  const totals = useMemo(() => {
    const totalSold = groupRows.reduce((total, row) => total + row.quantitySold, 0);
    const totalRevenue = groupRows.reduce((total, row) => total + row.revenue, 0);
    const totalStock = groupRows.reduce((total, row) => total + row.stock, 0);
    const dailySales = groupRows.reduce((total, row) => total + row.dailySales, 0);
    const daysOfCover = dailySales > 0 ? totalStock / dailySales : null;
    const colors = new Set(groupRows.map(row => row.color).filter(Boolean));
    const sizes = new Set(groupRows.map(row => row.size).filter(Boolean));

    return {
      totalSold,
      totalRevenue,
      totalStock,
      dailySales,
      daysOfCover,
      colorCount: colors.size,
      sizeCount: sizes.size
    };
  }, [groupRows]);

  const colorBreakdown = useMemo(() => buildBreakdown(groupRows, 'color'), [groupRows]);
  const sizeBreakdown = useMemo(() => buildBreakdown(groupRows, 'size'), [groupRows]);
  const isRefreshing = isLoading && products.length > 0;
  const totalPages = Math.ceil(groupRows.length / itemsPerPage);
  const safeCurrentPage = Math.min(currentPage, totalPages || 1);
  const startIndex = (safeCurrentPage - 1) * itemsPerPage;
  const paginatedRows = groupRows.slice(startIndex, startIndex + itemsPerPage);

  if (isLoading && products.length === 0) {
    return <ProductGroupDetailsSkeleton />;
  }

  if (!groupName || groupRows.length === 0) {
    return (
      <div className="py-12 text-center">
        <p className="font-medium text-zinc-500 dark:text-dark-muted">Grupo de produtos não encontrado.</p>
        <Link to="/products" className="mt-4 inline-block font-bold text-brand-primary hover:underline">
          Voltar para produtos
        </Link>
      </div>
    );
  }

  return (
    <div className="space-y-6">
      <div className="flex flex-col gap-4 md:flex-row md:items-center md:justify-between">
        <div className="flex flex-col gap-4">
          <BackButton fallbackTo="/products" />

          <div className="flex items-center gap-4">
            <div className="flex h-16 w-16 items-center justify-center rounded-2xl border border-zinc-200 bg-white text-brand-primary shadow-sm dark:border-dark-border dark:bg-dark-card">
              <Package className="h-8 w-8" />
            </div>
            <div className="min-w-0">
              <p className="text-xs font-bold uppercase tracking-widest text-zinc-400 dark:text-dark-muted">
                Grupo · {formatNumber(groupRows.length)} SKUs · {formatNumber(totals.colorCount)} cores · {formatNumber(totals.sizeCount)} tamanhos
              </p>
              <h1 className="truncate text-2xl font-bold text-zinc-900 dark:text-dark-text" title={groupName}>{groupName}</h1>
            </div>
          </div>
        </div>

        <DateRangePicker
          dateRange={dateRange}
          onChange={(range) => {
            setDateRange(range);
            setCurrentPage(1);
          }}
        />
      </div>

      <RefreshStatus isRefreshing={isRefreshing} />

      <div className={isRefreshing ? 'refreshing-content space-y-6' : 'space-y-6'} aria-busy={isRefreshing}>
        <div className="grid grid-cols-1 gap-4 md:grid-cols-4">
          <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <p className="mb-1 text-xs font-bold uppercase tracking-widest text-dark-muted">Unidades vendidas</p>
                <p className="text-3xl font-bold text-dark-text">{formatNumber(totals.totalSold)}</p>
              </div>
              <Package className="h-6 w-6 text-brand-primary" />
            </div>
          </div>

          <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <p className="mb-1 text-xs font-bold uppercase tracking-widest text-dark-muted">Receita total</p>
                <p className="text-3xl font-bold text-dark-text">{formatCurrency(totals.totalRevenue)}</p>
              </div>
              <DollarSign className="h-6 w-6 text-emerald-300" />
            </div>
          </div>

          <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <p className="mb-1 text-xs font-bold uppercase tracking-widest text-dark-muted">Estoque</p>
                <p className="text-3xl font-bold text-dark-text">{formatNumber(totals.totalStock)}</p>
              </div>
              <Warehouse className="h-6 w-6 text-purple-300" />
            </div>
          </div>

          <div className="rounded-2xl border border-dark-border bg-dark-card p-5 shadow-sm">
            <div className="flex items-center justify-between gap-4">
              <div>
                <p className="mb-1 text-xs font-bold uppercase tracking-widest text-dark-muted">Cobertura estimada</p>
                <p className="text-3xl font-bold text-dark-text">{formatDays(totals.daysOfCover)}</p>
              </div>
              <TrendingDown className="h-6 w-6 text-sky-300" />
            </div>
          </div>
        </div>

        <div className="grid grid-cols-1 gap-4 xl:grid-cols-2">
          <BreakdownPanel
            title="Venda por cor"
            subtitle="Cores mais vendidas dentro deste grupo."
            rows={colorBreakdown}
            type="color"
          />
          <BreakdownPanel
            title="Venda por tamanho"
            subtitle="Tamanhos mais vendidos dentro deste grupo."
            rows={sizeBreakdown}
            type="size"
          />
        </div>

        <div className="overflow-hidden rounded-2xl border border-zinc-200 bg-white shadow-sm dark:border-dark-border dark:bg-dark-card">
          <div className="flex flex-col gap-2 border-b border-zinc-100 px-6 py-4 dark:border-dark-border md:flex-row md:items-end md:justify-between">
            <div>
              <h3 className="text-base font-bold text-zinc-900 dark:text-dark-text">Variações do grupo</h3>
              <p className="mt-1 text-sm font-medium text-zinc-500 dark:text-dark-muted">SKUs, cores e tamanhos que formam este grupo.</p>
            </div>
            <span className="text-xs font-bold uppercase tracking-widest text-zinc-400 dark:text-dark-muted">
              {formatNumber(groupRows.length)} SKUs
            </span>
          </div>
          <div className="overflow-x-auto">
            <table className="w-full min-w-[1100px] table-fixed text-left text-sm">
              <colgroup>
                <col className="w-[120px]" />
                <col className="w-[360px]" />
                <col className="w-[120px]" />
                <col className="w-[100px]" />
                <col className="w-[120px]" />
                <col className="w-[120px]" />
                <col className="w-[140px]" />
                <col className="w-[130px]" />
                <col className="w-[130px]" />
              </colgroup>
              <thead className="border-b border-zinc-100 bg-zinc-50 text-zinc-500 dark:border-dark-border dark:bg-dark-header dark:text-dark-muted">
                <tr>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">ID Produto</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Descrição</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Cor</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Tamanho</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Vendido</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Estoque</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Média diária</th>
                  <th className="px-6 py-4 text-[10px] font-bold uppercase tracking-wider">Receita</th>
                  <th className="px-6 py-4 text-right text-[10px] font-bold uppercase tracking-wider">Ações</th>
                </tr>
              </thead>
              <tbody className="divide-y divide-zinc-100 dark:divide-dark-border">
                {paginatedRows.map(row => (
                  <tr key={row.id} className="transition-colors hover:bg-zinc-50/80 dark:hover:bg-dark-input/50">
                    <td className="px-6 py-2.5 font-mono text-[11px] text-zinc-400 dark:text-dark-muted">#{row.id}</td>
                    <td className="max-w-0 px-6 py-2.5">
                      <div className="truncate font-semibold text-zinc-900 dark:text-dark-text" title={row.name}>{row.name}</div>
                      <div className="text-[10px] font-medium text-zinc-400 dark:text-dark-muted">Preço Atual: {formatCurrency(row.lastPrice)}</div>
                    </td>
                    <td className="px-6 py-2.5">
                      <span className="inline-flex max-w-full items-center gap-2 rounded-full border border-sky-400/25 bg-sky-400/10 px-2.5 py-1 text-xs font-bold text-sky-300">
                        <ColorSwatch label={row.color || 'Sem cor'} className="h-2 w-2" />
                        <span className="truncate">{row.color || '-'}</span>
                      </span>
                    </td>
                    <td className="px-6 py-2.5">
                      <span className="inline-flex rounded-full border border-emerald-400/25 bg-emerald-400/10 px-2.5 py-1 text-xs font-bold text-emerald-300">
                        {row.size || '-'}
                      </span>
                    </td>
                    <td className="px-6 py-2.5 whitespace-nowrap">
                      <div className="flex items-center gap-2">
                        <Package className="h-3.5 w-3.5 text-zinc-400 dark:text-dark-muted" />
                        <span className="font-bold text-zinc-900 dark:text-dark-text">{formatNumber(row.quantitySold)} un.</span>
                      </div>
                    </td>
                    <td className="px-6 py-2.5 whitespace-nowrap font-bold text-zinc-900 dark:text-dark-text">{formatNumber(row.stock)} un.</td>
                    <td className="px-6 py-2.5 whitespace-nowrap text-zinc-500 dark:text-dark-muted">{formatNumber(row.dailySales, 2)} un./dia</td>
                    <td className="px-6 py-2.5 whitespace-nowrap font-bold text-brand-primary">{formatCurrency(row.revenue)}</td>
                    <td className="px-4 py-2.5 text-right">
                      <Link
                        to={`/products/${row.id}`}
                        className="inline-flex items-center whitespace-nowrap rounded-lg bg-brand-primary/10 px-3 py-1.5 text-xs font-bold text-brand-primary transition-opacity hover:opacity-80"
                      >
                        <TrendingUp className="mr-1.5 h-3.5 w-3.5" />
                        Ver SKU
                      </Link>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
          <PaginationControls
            totalItems={groupRows.length}
            currentPage={safeCurrentPage}
            totalPages={totalPages}
            pageSize={itemsPerPage}
            pageSizeOptions={[10, 20, 50, 100]}
            itemLabel="SKUs"
            pageSizeLabel="SKUs por página"
            startIndex={startIndex}
            endIndex={Math.min(startIndex + itemsPerPage, groupRows.length)}
            onPageChange={setCurrentPage}
            onPageSizeChange={(pageSize) => {
              setItemsPerPage(pageSize);
              setCurrentPage(1);
            }}
          />
        </div>
      </div>
    </div>
  );
};

export default ProductGroupDetails;
