"use client";

import { useEffect, useMemo, useRef, useState } from "react";
import { ChevronDown, ChevronLeft, ChevronRight, ChevronUp, Columns3, Download, Search, Settings2 } from "lucide-react";
import type { ReportExportFormat, ReportSort, ReportTableColumn, ReportTableRow } from "@/lib/reports/contracts";
import { formatValueByType } from "@/lib/reports/utils";
import { Button } from "@/components/ui/button";
import { Checkbox } from "@/components/ui/checkbox";

type ReportDataTableProps = {
  columns: ReportTableColumn[];
  rows: ReportTableRow[];
  totalRows: number;
  page: number;
  pageSize: number;
  sort: ReportSort;
  visibleColumnIds: string[];
  search: string;
  onSearchChange: (value: string) => void;
  onPageChange: (page: number) => void;
  onSortChange: (value: ReportSort) => void;
  onVisibleColumnIdsChange: (value: string[]) => void;
  onExport: (format: ReportExportFormat) => void;
  busyExport: ReportExportFormat | null;
};

function nextSort(current: ReportSort, columnId: string): ReportSort {
  if (!current || current.columnId !== columnId) return { columnId, direction: "asc" };
  if (current.direction === "asc") return { columnId, direction: "desc" };
  return null;
}

export function ReportDataTable({
  columns,
  rows,
  totalRows,
  page,
  pageSize,
  sort,
  visibleColumnIds,
  search,
  onSearchChange,
  onPageChange,
  onSortChange,
  onVisibleColumnIdsChange,
  onExport,
  busyExport,
}: ReportDataTableProps) {
  const visibleColumns = useMemo(
    () => columns.filter((column) => visibleColumnIds.includes(column.id)),
    [columns, visibleColumnIds]
  );
  const [menuOpen, setMenuOpen] = useState(false);
  const [exportMenuOpen, setExportMenuOpen] = useState(false);
  const [columnWidths, setColumnWidths] = useState<Record<string, number>>({});
  const resizeStateRef = useRef<{ columnId: string; startX: number; startWidth: number } | null>(null);
  const menuRef = useRef<HTMLDivElement | null>(null);
  const exportMenuRef = useRef<HTMLDivElement | null>(null);
  const totalPages = Math.max(1, Math.ceil(totalRows / pageSize));
  const rangeStart = totalRows === 0 ? 0 : (page - 1) * pageSize + 1;
  const rangeEnd = Math.min(totalRows, page * pageSize);
  const pageNumbers = useMemo(() => {
    const pages = new Set<number>([1, totalPages, page - 1, page, page + 1].filter((value) => value >= 1 && value <= totalPages));
    return Array.from(pages).sort((left, right) => left - right);
  }, [page, totalPages]);

  useEffect(() => {
    function handleClickOutside(event: MouseEvent) {
      if (menuRef.current && !menuRef.current.contains(event.target as Node)) {
        setMenuOpen(false);
      }
      if (exportMenuRef.current && !exportMenuRef.current.contains(event.target as Node)) {
        setExportMenuOpen(false);
      }
    }

    function handlePointerMove(event: MouseEvent) {
      const active = resizeStateRef.current;
      if (!active) return;
      const nextWidth = Math.max(96, active.startWidth + (event.clientX - active.startX));
      setColumnWidths((current) => ({ ...current, [active.columnId]: nextWidth }));
    }

    function handlePointerUp() {
      resizeStateRef.current = null;
    }

    window.addEventListener("mousedown", handleClickOutside);
    window.addEventListener("mousemove", handlePointerMove);
    window.addEventListener("mouseup", handlePointerUp);
    return () => {
      window.removeEventListener("mousedown", handleClickOutside);
      window.removeEventListener("mousemove", handlePointerMove);
      window.removeEventListener("mouseup", handlePointerUp);
    };
  }, []);

  function renderCell(column: ReportTableColumn, row: ReportTableRow) {
    const rawValue = row[column.id] ?? null;
    const formatted = formatValueByType(rawValue, column.type);
    const valueText = String(rawValue ?? "").toLowerCase();
    const typeText = String(row.type ?? "").toLowerCase();

    if (column.type === "badge") {
      const tone =
        valueText.includes("atras") || valueText.includes("cancel") || valueText.includes("rejeit") || valueText.includes("inativo")
          ? "border-red-100 bg-red-50 text-red-600"
          : valueText.includes("pend") || valueText.includes("parcial") || valueText.includes("base") || valueText.includes("sem ")
            ? "border-amber-100 bg-amber-50 text-amber-700"
            : valueText.includes("receb") || valueText.includes("pago") || valueText.includes("ativo") || valueText.includes("aprov") || valueText.includes("concl")
              ? "border-emerald-100 bg-emerald-50 text-emerald-700"
              : "border-slate-200 bg-slate-50 text-slate-600";

      return (
        <span className={`inline-flex rounded-full border px-2 py-1 text-[11px] font-medium leading-none ${tone}`}>
          {formatted}
        </span>
      );
    }

    if (column.id.toLowerCase().includes("type")) {
      const display = valueText.includes("entrada") ? "Receita" : valueText.includes("saída") || valueText.includes("saida") ? "Despesa" : formatted;
      const tone = display === "Despesa" ? "text-red-600" : display === "Receita" ? "text-emerald-600" : "text-slate-700";
      return <span className={`font-semibold ${tone}`}>{display}</span>;
    }

    if (column.type === "currency") {
      const isNegative =
        Number(rawValue) < 0 ||
        valueText.includes("despesa") ||
        valueText.includes("saída") ||
        typeText.includes("saída") ||
        typeText.includes("despesa");
      return <span className={isNegative ? "font-semibold text-red-600" : "font-semibold text-slate-900"}>{formatted}</span>;
    }

    return <span>{formatted}</span>;
  }

  return (
    <section className="overflow-hidden rounded-2xl border border-gray-100 bg-white shadow-none">
      <div className="flex flex-col gap-4 border-b border-gray-100 px-5 py-4 lg:px-6">
        <div className="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h3 className="text-[15px] font-semibold text-[var(--ks-color-text-primary)]">Tabela analítica</h3>
            <p className="mt-1 text-xs text-[var(--ks-color-text-soft)]">
              Grade consolidada com busca, ordenação, controle de colunas e exportação.
            </p>
          </div>

          <div className="flex items-center gap-2">
            <div className="relative" ref={menuRef}>
              <Button
                type="button"
                variant="secondary"
                size="sm"
                icon={<Columns3 className="h-4 w-4" />}
                onClick={() => setMenuOpen((current) => !current)}
                className="rounded-xl border border-gray-100 bg-white text-slate-700 shadow-none"
              >
                Colunas
              </Button>
              {menuOpen ? (
                <div className="absolute right-0 top-11 z-20 w-72 rounded-2xl border border-gray-100 bg-white p-3 shadow-[0_14px_30px_rgba(15,23,42,0.08)]">
                  <div className="mb-2 flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--ks-color-text-soft)]">
                    <Settings2 className="h-4 w-4" />
                    Seleção de colunas
                  </div>
                  <div className="grid grid-cols-1 gap-1">
                    {columns.map((column) => {
                      const checked = visibleColumnIds.includes(column.id);
                      return (
                        <label key={column.id} className="flex items-center gap-2 rounded-lg px-2 py-1.5 hover:bg-[rgba(148,163,184,0.08)]">
                          <Checkbox
                            checked={checked}
                            onCheckedChange={(nextChecked) => {
                              if (nextChecked) {
                                onVisibleColumnIdsChange([...visibleColumnIds, column.id]);
                              } else if (visibleColumnIds.length > 1) {
                                onVisibleColumnIdsChange(visibleColumnIds.filter((id) => id !== column.id));
                              }
                            }}
                          />
                          <span className="text-sm text-[var(--ks-color-text-primary)]">{column.label}</span>
                        </label>
                      );
                    })}
                  </div>
                </div>
              ) : null}
            </div>

            <div className="relative" ref={exportMenuRef}>
              <Button
                type="button"
                variant="secondary"
                size="sm"
                icon={<Download className="h-4 w-4" />}
                onClick={() => setExportMenuOpen((current) => !current)}
                className="rounded-xl border border-gray-100 bg-white text-slate-700 shadow-none"
              >
                Exportar
              </Button>
              {exportMenuOpen ? (
                <div className="absolute right-0 top-11 z-20 min-w-[180px] rounded-2xl border border-gray-100 bg-white p-1.5 shadow-[0_14px_30px_rgba(15,23,42,0.08)]">
                  {[
                    { key: "pdf", label: "PDF" },
                    { key: "xlsx", label: "Excel" },
                    { key: "csv", label: "CSV" },
                    { key: "print", label: "Impressão" },
                  ].map((item) => (
                    <button
                      key={item.key}
                      type="button"
                      className="flex w-full items-center justify-between rounded-xl px-3 py-2 text-sm text-slate-700 transition hover:bg-slate-50 disabled:cursor-not-allowed disabled:opacity-60"
                      disabled={busyExport === item.key}
                      onClick={() => {
                        setExportMenuOpen(false);
                        onExport(item.key as ReportExportFormat);
                      }}
                    >
                      <span>{item.label}</span>
                      {busyExport === item.key ? <span className="text-xs text-[var(--ks-color-text-soft)]">Processando</span> : null}
                    </button>
                  ))}
                </div>
              ) : null}
            </div>
          </div>
        </div>

        <div className="flex flex-col gap-3 lg:flex-row lg:items-center lg:justify-between">
          <div className="relative w-full max-w-[420px]">
            <Search className="pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--ks-color-text-soft)]" />
            <input
              value={search}
              onChange={(event) => onSearchChange(event.target.value)}
              placeholder="Buscar por cliente, descrição, status ou valor"
              className="h-10 w-full rounded-xl border border-gray-100 bg-white pl-9 pr-3 text-sm text-[var(--ks-color-text-primary)] outline-none transition focus:border-[var(--ks-color-primary)]"
            />
          </div>
          <div className="text-xs text-[var(--ks-color-text-muted)]">
            Exibindo {rangeStart}-{rangeEnd} de {totalRows} registros
          </div>
        </div>
      </div>

      <div className="overflow-auto">
        <div className="min-w-[1180px]">
          <table className="w-full border-separate border-spacing-0 text-[13px]">
            <thead className="sticky top-0 z-10">
              <tr>
                {visibleColumns.map((column) => {
                  const activeSort = sort?.columnId === column.id ? sort.direction : null;
                  const currentWidth = columnWidths[column.id] ?? column.width ?? column.minWidth ?? 140;
                  return (
                    <th
                      key={column.id}
                      style={{ width: currentWidth, minWidth: column.minWidth ?? 96 }}
                      className={`border-b border-gray-100 bg-[#fafafa] px-4 py-3.5 text-[11px] font-semibold uppercase tracking-[0.08em] text-slate-500 ${column.align === "right" ? "text-right" : "text-left"}`}
                    >
                      <div className="flex items-center justify-between gap-2">
                        <button
                          type="button"
                          className="flex min-w-0 items-center gap-1 text-left"
                          onClick={() => column.sortable !== false && onSortChange(nextSort(sort, column.id))}
                        >
                          <span className="truncate">{column.label}</span>
                          {column.sortable !== false ? (
                            activeSort === "asc" ? (
                              <ChevronUp className="h-4 w-4 shrink-0" />
                            ) : activeSort === "desc" ? (
                              <ChevronDown className="h-4 w-4 shrink-0" />
                            ) : (
                              <ChevronDown className="h-4 w-4 shrink-0 opacity-40" />
                            )
                          ) : null}
                        </button>
                        <button
                          type="button"
                          aria-label={`Redimensionar ${column.label}`}
                          className="h-6 w-2 shrink-0 cursor-col-resize rounded bg-transparent hover:bg-[rgba(59,130,246,0.14)]"
                          onMouseDown={(event) => {
                            resizeStateRef.current = {
                              columnId: column.id,
                              startX: event.clientX,
                              startWidth: currentWidth,
                            };
                          }}
                        />
                      </div>
                    </th>
                  );
                })}
              </tr>
            </thead>
            <tbody>
              {rows.length > 0 ? (
                rows.map((row, rowIndex) => (
                  <tr key={`row-${rowIndex}`} className="transition hover:bg-[rgba(59,130,246,0.04)]">
                    {visibleColumns.map((column) => (
                      <td
                        key={`${rowIndex}-${column.id}`}
                        className={`border-b border-gray-100 px-4 py-2.5 align-middle text-slate-700 ${column.align === "right" ? "text-right" : "text-left"}`}
                      >
                        <div className="truncate">{renderCell(column, row)}</div>
                      </td>
                    ))}
                  </tr>
                ))
              ) : (
                <tr>
                  <td colSpan={visibleColumns.length} className="px-4 py-10 text-center text-sm text-[var(--ks-color-text-muted)]">
                    Nenhum registro encontrado para os filtros atuais.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

      <div className="flex flex-col gap-3 border-t border-gray-100 px-5 py-3 lg:px-6 md:flex-row md:items-center md:justify-between">
        <div className="text-xs text-[var(--ks-color-text-muted)]">
          Página {page} de {totalPages}
        </div>
        <div className="flex items-center gap-1.5">
          <Button
            type="button"
            variant="secondary"
            size="sm"
            className="rounded-lg border border-[rgba(226,232,240,0.95)] bg-white text-slate-700 shadow-none"
            disabled={page <= 1}
            onClick={() => onPageChange(page - 1)}
            icon={<ChevronLeft className="h-4 w-4" />}
          >
            Anterior
          </Button>
          {pageNumbers.map((pageNumber, index) => {
            const previousPage = pageNumbers[index - 1];
            const needsGap = previousPage && pageNumber - previousPage > 1;
            return (
              <div key={`page-${pageNumber}`} className="flex items-center gap-1.5">
                {needsGap ? <span className="px-1 text-sm text-slate-400">...</span> : null}
                <button
                  type="button"
                  onClick={() => onPageChange(pageNumber)}
                  className={`flex h-8 min-w-8 items-center justify-center rounded-lg px-2 text-sm transition ${
                    pageNumber === page
                      ? "bg-[#4f46e5] text-white"
                      : "border border-[rgba(226,232,240,0.95)] bg-white text-slate-700 hover:bg-slate-50"
                  }`}
                >
                  {pageNumber}
                </button>
              </div>
            );
          })}
          <Button
            type="button"
            variant="secondary"
            size="sm"
            className="rounded-lg border border-[rgba(226,232,240,0.95)] bg-white text-slate-700 shadow-none"
            disabled={page >= totalPages}
            onClick={() => onPageChange(page + 1)}
            iconRight={<ChevronRight className="h-4 w-4" />}
          >
            Próxima
          </Button>
        </div>
      </div>
    </section>
  );
}
