"use client";

import { useState, useMemo, useCallback, useRef, useEffect } from "react";
import {
  ChevronUp,
  ChevronDown,
  ChevronsUpDown,
  Search,
  X,
  Download,
} from "lucide-react";

interface ColumnDef {
  key: string;
  label: string;
}

interface DataTableProps {
  /** The GeoJSON to extract tabular data from */
  geojson: GeoJSON.FeatureCollection;
  /** Column definitions (key = property name, label = display name) */
  columns: ColumnDef[];
  /** Optional: property key used for the "name" column (e.g., "name" or "mnemonic") */
  nameKey?: string;
  /** Called when a row is hovered */
  onRowHover?: (featureIndex: number | null) => void;
  /** Called when a row is clicked */
  onRowClick?: (featureIndex: number) => void;
  /** Currently highlighted feature index (from map hover) */
  highlightedIndex?: number | null;
}

type SortDir = "asc" | "desc" | null;

export function DataTable({
  geojson,
  columns,
  nameKey = "name",
  onRowHover,
  onRowClick,
  highlightedIndex,
}: DataTableProps) {
  const [searchQuery, setSearchQuery] = useState("");
  const [sortKey, setSortKey] = useState<string | null>(null);
  const [sortDir, setSortDir] = useState<SortDir>(null);
  const tableRef = useRef<HTMLDivElement>(null);
  const highlightedRowRef = useRef<HTMLTableRowElement>(null);

  // Extract rows from GeoJSON features
  type Row = { __idx: number; __name: string; [k: string]: unknown };
  const rows = useMemo<Row[]>(() => {
    return geojson.features.map((f, idx) => ({
      ...f.properties,
      __idx: idx,
      __name: String(f.properties?.[nameKey] ?? `#${idx + 1}`),
    } as Row));
  }, [geojson, nameKey]);

  // Filter
  const filteredRows = useMemo(() => {
    if (!searchQuery.trim()) return rows;
    const q = searchQuery.toLowerCase();
    return rows.filter((row) => {
      // Search in name
      if (row.__name.toLowerCase().includes(q)) return true;
      // Search in all column values
      for (const col of columns) {
        const val = row[col.key];
        if (val != null && String(val).toLowerCase().includes(q)) return true;
      }
      return false;
    });
  }, [rows, searchQuery, columns]);

  // Sort
  const sortedRows = useMemo(() => {
    if (!sortKey || !sortDir) return filteredRows;
    return [...filteredRows].sort((a, b) => {
      let va = sortKey === "__name" ? a.__name : a[sortKey];
      let vb = sortKey === "__name" ? b.__name : b[sortKey];

      // Try numeric comparison
      const na = Number(va);
      const nb = Number(vb);
      if (!isNaN(na) && !isNaN(nb)) {
        return sortDir === "asc" ? na - nb : nb - na;
      }

      // String comparison
      const sa = String(va ?? "");
      const sb = String(vb ?? "");
      const cmp = sa.localeCompare(sb, "ro");
      return sortDir === "asc" ? cmp : -cmp;
    });
  }, [filteredRows, sortKey, sortDir]);

  // Toggle sort
  const handleSort = useCallback(
    (key: string) => {
      if (sortKey === key) {
        if (sortDir === "asc") setSortDir("desc");
        else if (sortDir === "desc") {
          setSortKey(null);
          setSortDir(null);
        }
      } else {
        setSortKey(key);
        setSortDir("asc");
      }
    },
    [sortKey, sortDir]
  );

  // Scroll to highlighted row when map hover changes
  useEffect(() => {
    if (
      highlightedIndex != null &&
      highlightedRowRef.current &&
      tableRef.current
    ) {
      const container = tableRef.current;
      const row = highlightedRowRef.current;
      const containerRect = container.getBoundingClientRect();
      const rowRect = row.getBoundingClientRect();

      if (
        rowRect.top < containerRect.top + 40 ||
        rowRect.bottom > containerRect.bottom
      ) {
        row.scrollIntoView({ block: "center", behavior: "smooth" });
      }
    }
  }, [highlightedIndex]);

  // Sort icon
  const SortIcon = ({ colKey }: { colKey: string }) => {
    if (sortKey !== colKey)
      return <ChevronsUpDown size={12} className="dt-sort-icon dt-sort-icon--neutral" />;
    if (sortDir === "asc")
      return <ChevronUp size={12} className="dt-sort-icon dt-sort-icon--active" />;
    return <ChevronDown size={12} className="dt-sort-icon dt-sort-icon--active" />;
  };

  // Format value for display
  const formatValue = (val: unknown): string => {
    if (val == null || val === "") return "—";
    if (typeof val === "number") {
      if (Number.isInteger(val)) return val.toLocaleString("ro-RO");
      return val.toLocaleString("ro-RO", {
        minimumFractionDigits: 1,
        maximumFractionDigits: 2,
      });
    }
    return String(val);
  };

  // CSV export
  const handleExportCSV = useCallback(() => {
    const header = ["Nume", ...columns.map((c) => c.label)].join(",");
    const csvRows = sortedRows.map((row) => {
      const vals = [
        `"${row.__name}"`,
        ...columns.map((c) => {
          const v = row[c.key];
          if (v == null) return "";
          return typeof v === "string" ? `"${v.replace(/"/g, '""')}"` : String(v);
        }),
      ];
      return vals.join(",");
    });

    const csv = [header, ...csvRows].join("\n");
    const blob = new Blob(["\uFEFF" + csv], { type: "text/csv;charset=utf-8;" });
    const url = URL.createObjectURL(blob);
    const a = document.createElement("a");
    a.href = url;
    a.download = "datahub_preview.csv";
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, [sortedRows, columns]);

  return (
    <div className="dt">
      {/* Toolbar */}
      <div className="dt-toolbar">
        <div className="dt-search">
          <Search size={14} className="dt-search__icon" />
          <input
            type="text"
            className="dt-search__input"
            placeholder="Caută..."
            value={searchQuery}
            onChange={(e) => setSearchQuery(e.target.value)}
          />
          {searchQuery && (
            <button
              className="dt-search__clear"
              onClick={() => setSearchQuery("")}
              aria-label="Șterge căutarea"
            >
              <X size={12} />
            </button>
          )}
        </div>
        <div className="dt-toolbar__meta">
          <span className="dt-toolbar__count">
            {sortedRows.length}
            {filteredRows.length !== rows.length && ` / ${rows.length}`} rânduri
          </span>
          <button
            className="dt-toolbar__export"
            onClick={handleExportCSV}
            title="Exportă CSV"
          >
            <Download size={13} />
            CSV
          </button>
        </div>
      </div>

      {/* Table */}
      <div className="dt-scroll" ref={tableRef}>
        <table className="dt-table">
          <thead>
            <tr>
              <th className="dt-th dt-th--sticky dt-th--name" onClick={() => handleSort("__name")}>
                <span>Nume</span>
                <SortIcon colKey="__name" />
              </th>
              {columns.map((col) => (
                <th
                  key={col.key}
                  className="dt-th dt-th--data"
                  onClick={() => handleSort(col.key)}
                  title={col.label}
                >
                  <span>{col.label}</span>
                  <SortIcon colKey={col.key} />
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {sortedRows.map((row) => {
              const isHighlighted = highlightedIndex === row.__idx;
              return (
                <tr
                  key={row.__idx}
                  ref={isHighlighted ? highlightedRowRef : undefined}
                  className={`dt-tr${isHighlighted ? " dt-tr--highlighted" : ""}`}
                  onMouseEnter={() => onRowHover?.(row.__idx)}
                  onMouseLeave={() => onRowHover?.(null)}
                  onClick={() => onRowClick?.(row.__idx)}
                >
                  <td className="dt-td dt-td--sticky dt-td--name">{row.__name}</td>
                  {columns.map((col) => (
                    <td key={col.key} className="dt-td dt-td--data">
                      {formatValue(row[col.key])}
                    </td>
                  ))}
                </tr>
              );
            })}
            {sortedRows.length === 0 && (
              <tr>
                <td
                  colSpan={columns.length + 1}
                  className="dt-td"
                  style={{ textAlign: "center", padding: "24px", color: "var(--color-text-muted)" }}
                >
                  {searchQuery
                    ? `Niciun rezultat pentru „${searchQuery}"`
                    : "Nu sunt date de afișat"}
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>
    </div>
  );
}
