'use client';

import * as React from "react";
import {
  useReactTable,
  getCoreRowModel,
  getSortedRowModel,
  getFilteredRowModel,
  flexRender,
} from "@tanstack/react-table";
import { useVirtualizer } from "@tanstack/react-virtual";
import { Card, CardContent } from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  Select,
  SelectTrigger,
  SelectValue,
  SelectContent,
  SelectItem,
} from "@/components/ui/select";
import { ChevronUp, ChevronDown, Download } from "lucide-react";
import * as XLSX from 'xlsx';

interface AnaliticoItem {
  codigo_grupo: string;
  codigo_subgrupo: string;
  codigo_fornecedor: string;
  nome_fornecedor: string;
  id: number;
  codfilial: string;
  recnum: number;
  data_competencia: string;
  data_vencimento: string;
  data_pagamento: string;
  data_caixa: string;
  codigo_conta: string;
  conta: string;
  codigo_centrocusto: string;
  valor: number;
  historico: string;
  historico2: string;
  created_at: string;
  updated_at: string;
}

interface AnaliticoProps {
  filtros: {
    dataInicio: string;
    dataFim: string;
    centroCusto?: string;
    codigoGrupo?: string;
    codigoSubgrupo?: string;
    codigoConta?: string;
  };
}

export default function AnaliticoComponent({ filtros }: AnaliticoProps) {
  const [data, setData] = React.useState<AnaliticoItem[]>([]);
  const [loading, setLoading] = React.useState(false);
  const [globalFilter, setGlobalFilter] = React.useState("");
  const [columnFilters, setColumnFilters] = React.useState<any[]>([]);
  const [open, setOpen] = React.useState(false);
  const [conditions, setConditions] = React.useState([{ column: "", operator: "contains", value: "" }]);
  const [isScrolled, setIsScrolled] = React.useState(false);

  const fetchData = React.useCallback(async () => {
    // Só faz a requisição se tiver dataInicio e dataFim
    if (!filtros.dataInicio || !filtros.dataFim) {
      setData([]);
      return;
    }

    setLoading(true);
    try {
      const params = new URLSearchParams({
        dataInicio: filtros.dataInicio,
        dataFim: filtros.dataFim,
        ...(filtros.centroCusto && { centroCusto: filtros.centroCusto }),
        ...(filtros.codigoGrupo && { codigoGrupo: filtros.codigoGrupo }),
        ...(filtros.codigoSubgrupo && {
          codigoSubgrupo: filtros.codigoSubgrupo,
        }),
        ...(filtros.codigoConta && { codigoConta: filtros.codigoConta }),
      });

      const response = await fetch(`/api/analitico?${params}`);
      if (response.ok) {
        const result = await response.json();
        setData(result as AnaliticoItem[]);
      } else {
        console.error('Erro ao buscar dados:', await response.text());
      }
    } catch (error) {
      console.error('Erro ao buscar dados:', error);
    } finally {
      setLoading(false);
    }
  }, [filtros]);

  React.useEffect(() => {
    fetchData();
  }, [fetchData]);

  const columns = React.useMemo(
    () => [
      { 
        accessorKey: "data_competencia", 
        header: "Data Comp.", 
        filterFn: "advancedText",
        cell: ({ getValue }: { getValue: () => string }) => {
          const value = getValue();
          return new Date(value).toLocaleDateString('pt-BR');
        }
      },
      { 
        accessorKey: "data_vencimento", 
        header: "Data Venc.", 
        filterFn: "advancedText",
        cell: ({ getValue }: { getValue: () => string }) => {
          const value = getValue();
          return new Date(value).toLocaleDateString('pt-BR');
        }
      },
      { 
        accessorKey: "data_caixa", 
        header: "Data Caixa", 
        filterFn: "advancedText",
        cell: ({ getValue }: { getValue: () => string }) => {
          const value = getValue();
          return new Date(value).toLocaleDateString('pt-BR');
        }
      },
      { accessorKey: "codigo_fornecedor", header: "Cód. Fornec.", filterFn: "advancedText" },
      { accessorKey: "nome_fornecedor", header: "Fornecedor", filterFn: "advancedText" },
      { accessorKey: "codigo_centrocusto", header: "Cód. Centro", filterFn: "advancedText" },
      { accessorKey: "codigo_conta", header: "Cód. Conta", filterFn: "advancedText" },
      { accessorKey: "conta", header: "Conta", filterFn: "advancedText" },
      { 
        accessorKey: "valor", 
        header: "Valor", 
        filterFn: "advancedText",
        cell: ({ getValue }: { getValue: () => number }) => {
          const value = getValue();
          const formatted = new Intl.NumberFormat('pt-BR', {
            style: 'currency',
            currency: 'BRL',
          }).format(value);
          const isNegative = value < 0;
          return (
            <span className={isNegative ? 'text-red-600' : 'text-gray-900'}>
              {formatted}
            </span>
          );
        }
      },
      { accessorKey: "historico", header: "Histórico", filterFn: "advancedText" },
      { accessorKey: "historico2", header: "Histórico 2", filterFn: "advancedText" },
      { accessorKey: "recnum", header: "Recnum", filterFn: "advancedText" },
    ],
    []
  );

  const filterFns = React.useMemo(
    () => ({
      advancedText: (row: any, columnId: string, filters: any[]) => {
        if (!filters || filters.length === 0) return true;
  
        // Se veio um único filtro (objeto), transforma em array
        const conds = Array.isArray(filters) ? filters : [filters];
  
        // A coluna deve atender a todas as condições aplicáveis a ela
        return conds.every((filter) => {
          const raw = row.getValue(columnId);
          const v = raw == null ? "" : String(raw);
          const op = filter.operator;
          const q = (filter.value ?? "").toString();
          const a = v.toLowerCase();
          const b = q.toLowerCase();
  
          switch (op) {
            case "contains":
              return a.includes(b);
            case "equals":
              return a === b;
            case "startsWith":
              return a.startsWith(b);
            case "endsWith":
              return a.endsWith(b);
            case "empty":
              return a.length === 0;
            case "notEmpty":
              return a.length > 0;
            default:
              return true;
          }
        });
      },
    }),
    []
  );
  

  const table = useReactTable({
    data,
    columns,
    state: { globalFilter, columnFilters },
    onGlobalFilterChange: setGlobalFilter,
    onColumnFiltersChange: setColumnFilters,
    filterFns,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getSortedRowModel: getSortedRowModel(),
  });

  const parentRef = React.useRef<HTMLDivElement>(null);
  const rowVirtualizer = useVirtualizer({
    count: table.getRowModel().rows.length,
    getScrollElement: () => parentRef.current,
    estimateSize: () => 36,
    overscan: 20,
  });

  const virtualRows = rowVirtualizer.getVirtualItems();

  React.useEffect(() => {
    const handleScroll = () => {
      if (!parentRef.current) return;
      setIsScrolled(parentRef.current.scrollTop > 0);
    };
    const el = parentRef.current;
    el?.addEventListener("scroll", handleScroll);
    return () => el?.removeEventListener("scroll", handleScroll);
  }, []);

  const applyFilters = () => {
    // Agrupar múltiplas condições por coluna
    const grouped: Record<string, any[]> = {};
  
    conditions.forEach((c) => {
      if (
        c.column &&
        (c.operator === "empty" || c.operator === "notEmpty" || (c.value ?? "") !== "")
      ) {
        if (!grouped[c.column]) grouped[c.column] = [];
        grouped[c.column].push({ operator: c.operator, value: c.value });
      }
    });
  
    // Converte em formato aceito pelo TanStack
    const filters = Object.keys(grouped).map((col) => ({
      id: col,
      value: grouped[col],
    }));
  
    setColumnFilters(filters);
    setOpen(false);
  };

  const clearFilters = () => {
    setConditions([{ column: "", operator: "contains", value: "" }]);
    setColumnFilters([]);
  };

  const totalValor = data.reduce((sum, item) => {
    const valor =
      typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor;
    return sum + (isNaN(valor) ? 0 : valor);
  }, 0);

  const exportToExcel = () => {
    if (data.length === 0) return;

    // Preparar dados para exportação
    const exportData = data.map((item) => ({
      'Data Competência': new Date(item.data_competencia).toLocaleDateString(
        'pt-BR'
      ),
      'Data Vencimento': new Date(item.data_vencimento).toLocaleDateString(
        'pt-BR'
      ),
      'Data Caixa': new Date(item.data_caixa).toLocaleDateString('pt-BR'),
      'Código Fornecedor': item.codigo_fornecedor,
      Fornecedor: item.nome_fornecedor,
      'Código Centro Custo': item.codigo_centrocusto,
      'Centro Custo': item.codigo_centrocusto, // Assumindo que é o mesmo valor
      'Código Conta': item.codigo_conta,
      Conta: item.conta,
      Valor:
        typeof item.valor === 'string' ? parseFloat(item.valor) : item.valor,
      Histórico: item.historico,
      'Histórico 2': item.historico2,
      Recnum: item.recnum,
    }));

    // Criar workbook
    const wb = XLSX.utils.book_new();
    const ws = XLSX.utils.json_to_sheet(exportData);

    // Adicionar resumo na segunda aba
    const resumoData = [
      { Métrica: 'Total de Registros', Valor: data.length },
      { Métrica: 'Valor Total', Valor: totalValor },
    ];
    const wsResumo = XLSX.utils.json_to_sheet(resumoData);

    // Adicionar abas ao workbook
    XLSX.utils.book_append_sheet(wb, ws, 'Dados Analíticos');
    XLSX.utils.book_append_sheet(wb, wsResumo, 'Resumo');

    // Gerar nome do arquivo com data e hora
    const now = new Date();
    const timestamp = now.toISOString().slice(0, 19).replace(/:/g, '-');
    const fileName = `analitico_${timestamp}.xlsx`;

    // Fazer download
    XLSX.writeFile(wb, fileName);
  };

  return (
    <Card className="w-full h-[85vh] shadow-xl rounded-2xl border-0 bg-gradient-to-br from-white to-gray-50/30">
      <CardContent className="p-6 h-full flex flex-col">
        <div className="flex justify-between mb-6 flex-wrap gap-4">
          <div className="flex items-center gap-3">
            <div className="w-10 h-10 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-lg flex items-center justify-center">
              <svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 19v-6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2a2 2 0 002-2zm0 0V9a2 2 0 012-2h2a2 2 0 012 2v10m-6 0a2 2 0 002 2h2a2 2 0 002-2m0 0V5a2 2 0 012-2h2a2 2 0 012 2v14a2 2 0 01-2 2h-2a2 2 0 01-2-2z" />
              </svg>
            </div>
            <div>
              <h2 className="text-xl font-bold text-gray-900">Análise Analítica</h2>
              <p className="text-sm text-gray-500">Relatório detalhado de transações</p>
            </div>
          </div>
          <div className="flex gap-3">
            <Input
              placeholder="Filtrar tudo..."
              value={globalFilter ?? ""}
              onChange={(e: React.ChangeEvent<HTMLInputElement>) => setGlobalFilter(e.target.value)}
              className="w-64 bg-white border-gray-300 focus:border-blue-500 focus:ring-blue-500"
            />
            <Button 
              variant="outline" 
              onClick={() => setOpen(true)}
              className="bg-white border-gray-300 hover:bg-blue-50 hover:border-blue-300 text-gray-700"
            >
              Filtros Avançados
            </Button>
            {data.length > 0 && (
              <Button
                onClick={exportToExcel}
                variant="outline"
                size="sm"
                className="flex items-center gap-2 bg-white border-gray-300 hover:bg-green-50 hover:border-green-300 text-gray-700"
              >
                <Download className="h-4 w-4" />
                Exportar XLSX
              </Button>
            )}
          </div>
      </div>

        <div className="relative flex-1 bg-white rounded-xl border border-gray-200 shadow-sm overflow-hidden">
          <table className="min-w-full border-collapse table-fixed">
            <thead
              className={`bg-gradient-to-r from-blue-50 to-indigo-50 sticky top-0 z-20 transition-all duration-200 ${isScrolled ? "shadow-lg" : "shadow-sm"}`}
            >
              {table.getHeaderGroups().map((hg) => (
                <tr key={hg.id}>
                  {hg.headers.map((header) => {
                    const sorted = header.column.getIsSorted();
                    return (
                      <th
                        key={header.id}
                        onClick={header.column.getToggleSortingHandler()}
                        className="text-left px-4 py-4 border-b border-gray-200 cursor-pointer select-none group hover:bg-blue-100/50 transition-colors duration-150 whitespace-nowrap"
                      >
                        <div className="flex items-center justify-between gap-2">
                          <span className="font-semibold text-gray-800 text-sm uppercase tracking-wide truncate">
                            {flexRender(header.column.columnDef.header, header.getContext())}
              </span>
                          <div className="flex flex-col flex-shrink-0">
                            {sorted === "asc" ? (
                              <ChevronUp className="w-4 h-4 text-blue-600" />
                            ) : sorted === "desc" ? (
                              <ChevronDown className="w-4 h-4 text-blue-600" />
                            ) : (
                              <div className="flex flex-col opacity-30 group-hover:opacity-60 transition-opacity">
                                <ChevronUp className="w-3 h-3 -mb-1" />
                                <ChevronDown className="w-3 h-3" />
                              </div>
            )}
          </div>
        </div>
                      </th>
                    );
                  })}
                </tr>
              ))}
            </thead>
          </table>

          <div ref={parentRef} className="overflow-auto h-full bg-white">
            <table className="min-w-full border-collapse table-fixed">
              <tbody
                style={{ height: `${rowVirtualizer.getTotalSize()}px`, position: "relative" }}
              >
                {loading ? (
                  <tr>
                    <td colSpan={columns.length} className="p-12 text-center">
                      <div className="flex flex-col items-center gap-3">
                        <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-blue-600"></div>
                        <span className="text-gray-500 font-medium">Carregando dados analíticos...</span>
            </div>
                    </td>
                  </tr>
                ) : virtualRows.length === 0 ? (
                  <tr>
                    <td colSpan={columns.length} className="p-12 text-center">
                      <div className="flex flex-col items-center gap-3">
                        <div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center">
                          <svg className="w-8 h-8 text-gray-400" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                            <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
                          </svg>
            </div>
                        <span className="text-gray-500 font-medium">Nenhum dado analítico encontrado para os filtros aplicados.</span>
            </div>
                    </td>
                  </tr>
                ) : (
                  virtualRows.map((virtualRow) => {
                    const row = table.getRowModel().rows[virtualRow.index];
                    return (
                      <tr
                        key={row.id}
                        className="hover:bg-gradient-to-r hover:from-blue-50/30 hover:to-indigo-50/30 transition-all duration-150 border-b border-gray-100"
                        style={{
                          position: "absolute",
                          top: 0,
                          left: 0,
                          transform: `translateY(${virtualRow.start}px)`,
                          display: "table",
                          width: "100%",
                          tableLayout: "fixed",
                        }}
                      >
                        {row.getVisibleCells().map((cell, cellIndex) => (
                          <td 
                            key={cell.id} 
                            className={`px-4 py-3 text-sm whitespace-nowrap overflow-hidden ${
                              cellIndex === 0 ? 'font-medium text-gray-900' : 'text-gray-700'
                            } ${
                              cell.column.id === 'valor' ? 'text-right font-semibold' : ''
                            }`}
                            title={String(cell.getValue())}
                          >
                            <div className="truncate">
                              {flexRender(cell.column.columnDef.cell, cell.getContext())}
            </div>
                          </td>
                        ))}
                      </tr>
                    );
                  })
                )}
              </tbody>
            </table>
          </div>
        </div>

      {data.length > 0 && (
          <div className="mt-1 p-6 bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-xl shadow-sm">
          <div className="flex justify-between items-center">
              <div className="flex items-center gap-4">
                <div className="w-12 h-12 bg-gradient-to-r from-blue-600 to-indigo-600 rounded-lg flex items-center justify-center">
                  <svg className="w-6 h-6 text-white" fill="none" stroke="currentColor" viewBox="0 0 24 24">
                    <path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M9 7h6m0 10v-3m-3 3h.01M9 17h.01M9 14h.01M12 14h.01M15 11h.01M12 11h.01M9 11h.01M7 21h10a2 2 0 002-2V5a2 2 0 00-2-2H7a2 2 0 00-2 2v14a2 2 0 002 2z" />
                  </svg>
            </div>
            <div>
                  <h3 className="text-lg font-bold text-gray-900">
                    Total de Registros: <span className="text-blue-600">{table.getRowModel().rows.length}</span>
                  </h3>
                  <p className="text-sm text-gray-600">Transações encontradas</p>
                </div>
              </div>
              <div className="text-right">
                <h3 className="text-lg font-bold">
                  <span className={totalValor < 0 ? 'text-red-600' : 'text-green-600'}>
                    Valor Total: {new Intl.NumberFormat('pt-BR', {
                      style: 'currency',
                      currency: 'BRL',
                    }).format(totalValor)}
                    </span>
              </h3>
                <p className="text-sm text-gray-600">Soma de todos os valores</p>
            </div>
          </div>
        </div>
      )}

        <Dialog open={open} onOpenChange={setOpen}>
          <DialogContent className="max-w-2xl w-full mx-4 bg-white">
            <DialogHeader className="pb-4">
              <DialogTitle className="text-xl font-semibold text-gray-900">Filtros Avançados</DialogTitle>
            </DialogHeader>

            <div className="space-y-4 max-h-96 overflow-y-auto bg-white">
              {conditions.map((cond, idx) => (
                <div key={idx} className="flex gap-3 items-start p-4 bg-gray-50 rounded-lg border border-gray-200">
                  <div className="flex-1">
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      Coluna
                    </label>
                    <Select
                      value={cond.column}
                      onValueChange={(v: string) => {
                        const next = [...conditions];
                        next[idx].column = v;
                        setConditions(next);
                      }}
                    >
                      <SelectTrigger className="w-full bg-white border-gray-300">
                        <SelectValue placeholder="Selecione a coluna" />
                      </SelectTrigger>
                      <SelectContent>
                      {columns.map((col) => (
                        <SelectItem key={col.accessorKey} value={col.accessorKey}>
                          {col.header}
                        </SelectItem>
                      ))}
                      </SelectContent>
                    </Select>
                  </div>

                  <div className="flex-1">
                    <label className="block text-sm font-medium text-gray-700 mb-1">
                      Operador
                    </label>
                    <Select
                      value={cond.operator}
                      onValueChange={(v: string) => {
                        const next = [...conditions];
                        next[idx].operator = v;
                        if (v === "empty" || v === "notEmpty") next[idx].value = "";
                        setConditions(next);
                      }}
                    >
                      <SelectTrigger className="w-full bg-white border-gray-300">
                        <SelectValue placeholder="Selecione o operador" />
                      </SelectTrigger>
                      <SelectContent>
                        <SelectItem value="contains">contém</SelectItem>
                        <SelectItem value="equals">igual a</SelectItem>
                        <SelectItem value="startsWith">começa com</SelectItem>
                        <SelectItem value="endsWith">termina com</SelectItem>
                        <SelectItem value="empty">está vazio</SelectItem>
                        <SelectItem value="notEmpty">não está vazio</SelectItem>
                      </SelectContent>
                    </Select>
                  </div>

                  {!(cond.operator === "empty" || cond.operator === "notEmpty") && (
                    <div className="flex-1">
                      <label className="block text-sm font-medium text-gray-700 mb-1">
                        Valor
                      </label>
                      <Input
                        value={cond.value}
                        onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                          const next = [...conditions];
                          next[idx].value = e.target.value;
                          setConditions(next);
                        }}
                        placeholder="Digite o valor"
                        className="w-full bg-white border-gray-300"
                      />
                    </div>
                  )}

                  {conditions.length > 1 && (
                    <div className="flex items-end">
                      <Button
                        variant="outline"
                        size="sm"
                        onClick={() => {
                          const next = conditions.filter((_, i) => i !== idx);
                          setConditions(next);
                        }}
                        className="mt-6 text-red-600 hover:text-red-700 hover:bg-red-50 border-red-200"
                      >
                        ✕
                      </Button>
                    </div>
                  )}
                </div>
              ))}

              <div className="flex justify-center pt-2">
                <Button
                  variant="outline"
                  onClick={() =>
                    setConditions((prev) => [
                      ...prev,
                      { column: "", operator: "contains", value: "" },
                    ])
                  }
                  className="flex items-center gap-2 text-blue-600 hover:text-blue-700 hover:bg-blue-50 border-blue-200"
                >
                  <span className="text-lg">+</span>
                  Adicionar condição
                </Button>
              </div>
    </div>

            <DialogFooter className="flex gap-3 pt-6 border-t border-gray-200">
              <Button 
                variant="outline" 
                onClick={clearFilters}
                className="flex-1 border-gray-300 text-gray-700 hover:bg-gray-50"
              >
                Limpar todos
              </Button>
              <Button 
                onClick={applyFilters}
                className="flex-1 bg-blue-600 hover:bg-blue-700 text-white"
              >
                Aplicar filtros
              </Button>
            </DialogFooter>
          </DialogContent>
        </Dialog>
      </CardContent>
    </Card>
  );
}