"use client";

import { useState, useCallback, useEffect, useRef } from "react";
import {
  ChevronUp,
  ChevronDown,
  ChevronsUpDown,
  ChevronLeft,
  ChevronRight,
  ChevronsLeft,
  ChevronsRight,
  Search,
  X,
  Download,
  Info,
  Calendar,
} from "lucide-react";

interface ColumnInfo {
  name: string;
  type: string;
}

interface DatasetMeta {
  id: string;
  name: string;
  description: string;
  source: string;
  category?: string;
  subcategory?: string;
  periodicity?: string;
  temporal?: { type: string | null; values: string[] };
  geometry_levels: string[];
  join_key: string;
  columnsMeta?: Array<{ id: string; name: string; description: string; unit?: string }>;
}

interface PreviewResponse {
  dataset: DatasetMeta;
  columns: ColumnInfo[];
  rows: Record<string, unknown>[];
  totalRows: number;
  page: number;
  pageSize: number;
  totalPages: number;
}

interface DataPreviewProps {
  datasetId: string;
  level: string;
  collection: string;
  datasetMeta?: {
    name: string;
    description?: string;
    source?: string;
    category?: string;
    geometry_levels: string[];
  };
  onLevelChange: (level: string) => void;
}

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

export function DataPreview({
  datasetId,
  level,
  collection,
  datasetMeta,
  onLevelChange,
}: DataPreviewProps) {
  const [data, setData] = useState<PreviewResponse | null>(null);
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Pagination & query state
  const [page, setPage] = useState(1);
  const [pageSize, setPageSize] = useState(50);
  const [sortKey, setSortKey] = useState<string | null>(null);
  const [sortDir, setSortDir] = useState<SortDir>(null);
  const [searchQuery, setSearchQuery] = useState("");
  const [searchInput, setSearchInput] = useState("");
  const [infoOpen, setInfoOpen] = useState(false);
  const debounceRef = useRef<ReturnType<typeof setTimeout>>(null);

  // Fetch data
  const fetchData = useCallback(async () => {
    setLoading(true);
    setError(null);
    try {
      const params = new URLSearchParams({
        dataset: datasetId,
        level,
        collection,
        page: String(page),
        pageSize: String(pageSize),
      });
      if (sortKey && sortDir) {
        params.set("sort", sortKey);
        params.set("sortDir", sortDir);
      }
      if (searchQuery) {
        params.set("search", searchQuery);
      }

      const res = await fetch(`/datahub/api/explorer/preview?${params}`);
      if (!res.ok) {
        const err = await res.json();
        throw new Error(err.error || "Eroare la încărcarea datelor");
      }
      const json: PreviewResponse = await res.json();
      setData(json);
    } catch (err) {
      setError(err instanceof Error ? err.message : "Eroare necunoscută");
    } finally {
      setLoading(false);
    }
  }, [datasetId, level, collection, page, pageSize, sortKey, sortDir, searchQuery]);

  // Reset on dataset/level change
  useEffect(() => {
    setPage(1);
    setSortKey(null);
    setSortDir(null);
    setSearchQuery("");
    setSearchInput("");
  }, [datasetId, level, collection]);

  // Fetch on any query change
  useEffect(() => {
    fetchData();
  }, [fetchData]);

  // Debounced search
  const handleSearchInput = (val: string) => {
    setSearchInput(val);
    if (debounceRef.current) clearTimeout(debounceRef.current);
    debounceRef.current = setTimeout(() => {
      setSearchQuery(val);
      setPage(1);
    }, 400);
  };

  // Sort toggle
  const handleSort = (col: string) => {
    if (sortKey === col) {
      if (sortDir === "asc") {
        setSortDir("desc");
      } else {
        setSortKey(null);
        setSortDir(null);
      }
    } else {
      setSortKey(col);
      setSortDir("asc");
    }
    setPage(1);
  };

  // Format value
  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(() => {
    if (!data) return;
    const header = data.columns.map((c) => c.name).join(",");
    const csvRows = data.rows.map((row) =>
      data.columns
        .map((c) => {
          const v = row[c.name];
          if (v == null) return "";
          return typeof v === "string"
            ? `"${v.replace(/"/g, '""')}"`
            : String(v);
        })
        .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 = `${datasetId}_${level}_p${page}.csv`;
    document.body.appendChild(a);
    a.click();
    document.body.removeChild(a);
    URL.revokeObjectURL(url);
  }, [data, datasetId, level, page]);

  // Sort icon
  const SortIcon = ({ col }: { col: string }) => {
    if (sortKey !== col)
      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" />
    );
  };

  // Column display name from metadata
  const colLabel = (colName: string): string => {
    if (!data?.dataset.columnsMeta) return colName;
    const meta = data.dataset.columnsMeta.find((c) => c.id === colName);
    return meta?.name || colName;
  };

  if (!data && loading) {
    return (
      <div className="ds-preview__loading">
        <div className="spinner" />
        <span>Se încarcă datele...</span>
      </div>
    );
  }

  if (error) {
    return (
      <div className="ds-preview__error">
        <span>⚠</span> {error}
      </div>
    );
  }

  if (!data) return null;

  const { columns, rows, totalRows, totalPages } = data;
  const ds = data.dataset;

  return (
    <div className="ds-preview">
      {/* Header */}
      <div className="ds-preview__header">
        <div className="ds-preview__header-left">
          <h2 className="ds-preview__title">{ds.name}</h2>
          <div className="ds-preview__meta">
            <span className="ds-preview__id">{ds.id}</span>
            <span className="ds-preview__sep">·</span>
            <span>{totalRows.toLocaleString("ro-RO")} rânduri</span>
            <span className="ds-preview__sep">·</span>
            <span>{columns.length} coloane</span>
            {ds.temporal?.type && (
              <>
                <span className="ds-preview__sep">·</span>
                <Calendar size={12} style={{ display: "inline", verticalAlign: "middle" }} />
                <span>{ds.temporal.values.length} perioade</span>
              </>
            )}
          </div>
        </div>
        <div className="ds-preview__header-right">
          {/* Level toggle */}
          {ds.geometry_levels.length > 1 && (
            <div className="ds-preview__level-toggle">
              {ds.geometry_levels.map((lvl) => (
                <button
                  key={lvl}
                  className={`ds-preview__level-btn${level === lvl ? " ds-preview__level-btn--active" : ""}`}
                  onClick={() => onLevelChange(lvl)}
                >
                  {lvl === "county" ? "Județe" : lvl === "region" ? "Regiuni" : lvl.toUpperCase()}
                </button>
              ))}
            </div>
          )}
          <button
            className={`ds-preview__info-btn${infoOpen ? " ds-preview__info-btn--active" : ""}`}
            onClick={() => setInfoOpen((v) => !v)}
            title="Informații dataset"
          >
            <Info size={15} />
          </button>
        </div>
      </div>

      {/* Info panel (collapsible) */}
      {infoOpen && (
        <div className="ds-preview__info-panel">
          <p>{ds.description}</p>
          <div className="ds-preview__info-grid">
            <div>
              <strong>Sursă</strong>
              <span>{ds.source}</span>
            </div>
            {ds.category && (
              <div>
                <strong>Categorie</strong>
                <span>{ds.category}</span>
              </div>
            )}
            {ds.periodicity && (
              <div>
                <strong>Periodicitate</strong>
                <span>{ds.periodicity}</span>
              </div>
            )}
            <div>
              <strong>Cheie JOIN</strong>
              <span style={{ fontFamily: "monospace" }}>{ds.join_key}</span>
            </div>
          </div>
        </div>
      )}

      {/* Toolbar */}
      <div className="ds-preview__toolbar">
        <div className="dt-search">
          <Search size={14} className="dt-search__icon" />
          <input
            type="text"
            className="dt-search__input"
            placeholder="Caută în date..."
            value={searchInput}
            onChange={(e) => handleSearchInput(e.target.value)}
          />
          {searchInput && (
            <button
              className="dt-search__clear"
              onClick={() => {
                setSearchInput("");
                setSearchQuery("");
                setPage(1);
              }}
            >
              <X size={12} />
            </button>
          )}
        </div>

        <div className="ds-preview__toolbar-right">
          <select
            className="ds-preview__page-size"
            value={pageSize}
            onChange={(e) => {
              setPageSize(Number(e.target.value));
              setPage(1);
            }}
          >
            <option value={25}>25 / pag</option>
            <option value={50}>50 / pag</option>
            <option value={100}>100 / pag</option>
            <option value={200}>200 / pag</option>
          </select>
          <button
            className="dt-toolbar__export"
            onClick={handleExportCSV}
            title="Exportă CSV (pagina curentă)"
          >
            <Download size={13} />
            CSV
          </button>
        </div>
      </div>

      {/* Table */}
      <div className="ds-preview__table-wrap">
        {loading && (
          <div className="ds-preview__table-loading">
            <div className="spinner" />
          </div>
        )}
        <table className="dt-table">
          <thead>
            <tr>
              {columns.map((col) => (
                <th
                  key={col.name}
                  className={`dt-th${col.name === ds.join_key ? " dt-th--sticky dt-th--name" : " dt-th--data"}`}
                  onClick={() => handleSort(col.name)}
                  title={colLabel(col.name)}
                >
                  <span>{colLabel(col.name)}</span>
                  <SortIcon col={col.name} />
                </th>
              ))}
            </tr>
          </thead>
          <tbody>
            {rows.map((row, idx) => (
              <tr key={idx} className="dt-tr">
                {columns.map((col) => (
                  <td
                    key={col.name}
                    className={`dt-td${col.name === ds.join_key ? " dt-td--sticky dt-td--name" : " dt-td--data"}`}
                  >
                    {formatValue(row[col.name])}
                  </td>
                ))}
              </tr>
            ))}
            {rows.length === 0 && (
              <tr>
                <td
                  colSpan={columns.length}
                  className="dt-td"
                  style={{
                    textAlign: "center",
                    padding: 32,
                    color: "var(--color-text-muted)",
                  }}
                >
                  {searchQuery
                    ? `Niciun rezultat pentru „${searchQuery}"`
                    : "Nu sunt date"}
                </td>
              </tr>
            )}
          </tbody>
        </table>
      </div>

      {/* Pagination */}
      {totalPages > 1 && (
        <div className="ds-pagination">
          <div className="ds-pagination__info">
            Pagina {page} din {totalPages} ({totalRows.toLocaleString("ro-RO")}{" "}
            rânduri)
          </div>
          <div className="ds-pagination__controls">
            <button
              className="ds-pagination__btn"
              disabled={page <= 1}
              onClick={() => setPage(1)}
              title="Prima pagină"
            >
              <ChevronsLeft size={16} />
            </button>
            <button
              className="ds-pagination__btn"
              disabled={page <= 1}
              onClick={() => setPage((p) => p - 1)}
              title="Pagina anterioară"
            >
              <ChevronLeft size={16} />
            </button>

            {/* Page numbers */}
            {(() => {
              const pages: number[] = [];
              const start = Math.max(1, page - 2);
              const end = Math.min(totalPages, page + 2);
              for (let i = start; i <= end; i++) pages.push(i);
              return pages.map((p) => (
                <button
                  key={p}
                  className={`ds-pagination__btn ds-pagination__btn--page${p === page ? " ds-pagination__btn--active" : ""}`}
                  onClick={() => setPage(p)}
                >
                  {p}
                </button>
              ));
            })()}

            <button
              className="ds-pagination__btn"
              disabled={page >= totalPages}
              onClick={() => setPage((p) => p + 1)}
              title="Pagina următoare"
            >
              <ChevronRight size={16} />
            </button>
            <button
              className="ds-pagination__btn"
              disabled={page >= totalPages}
              onClick={() => setPage(totalPages)}
              title="Ultima pagină"
            >
              <ChevronsRight size={16} />
            </button>
          </div>
        </div>
      )}
    </div>
  );
}
