"use client";

import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import dynamic from "next/dynamic";
import Link from "next/link";
import {
  Globe,
  Pencil,
  Download,
  Layers,
  MapPin,
  Database,
  Info,
  X,
  ExternalLink,
  Construction,
  Github,
  Table2,
  ChevronDown,
  ChevronUp,
} from "lucide-react";
import {
  DataWizard,
  type WizardResult,
  type DatasetSelection,
} from "@/components/wizard/DataWizard";
import { DataTable } from "@/components/table/DataTable";
import type { GeometryLevel } from "@/types/geometry";
import type { Dataset } from "@/types/dataset";
import { GEOMETRY_LEVELS } from "@/types/geometry";
import { PALETTES, DEFAULT_PALETTE } from "@/lib/palettes";

// Lazy-load MapView to avoid SSR issues with MapLibre GL
const MapView = dynamic(
  () =>
    import("@/components/map/MapView").then((m) => ({ default: m.MapView })),
  {
    ssr: false,
    loading: () => (
      <div
        style={{
          width: "100%",
          height: "100%",
          background: "var(--color-bg-primary)",
          display: "flex",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        <div className="spinner" />
      </div>
    ),
  }
);

export default function HomePage() {
  // Wizard
  const [wizardOpen, setWizardOpen] = useState(true);

  // Selection state
  const [selectedLevel, setSelectedLevel] = useState<GeometryLevel | null>(null);
  const [simplified, setSimplified] = useState(true);
  const [selections, setSelections] = useState<DatasetSelection[]>([]);
  const [projection, setProjection] = useState<"EPSG:3844" | "EPSG:4326">("EPSG:3844");

  // All datasets
  const [allDatasets, setAllDatasets] = useState<Dataset[]>([]);
  const [loadingDatasets, setLoadingDatasets] = useState(false);

  // Map state
  const [previewGeojson, setPreviewGeojson] =
    useState<GeoJSON.FeatureCollection | null>(null);
  const [colorProperty, setColorProperty] = useState<string | undefined>();
  const [colorLabel, setColorLabel] = useState<string | undefined>();
  const [paletteId, setPaletteId] = useState(DEFAULT_PALETTE);

  // Info modal
  const [infoOpen, setInfoOpen] = useState(false);

  // Table panel
  const [tableOpen, setTableOpen] = useState(false);
  const [tableHeight, setTableHeight] = useState(320);
  const tableAreaRef = useRef<HTMLDivElement>(null);
  const resizingRef = useRef(false);

  // Loading
  const [previewing, setPreviewing] = useState(false);
  const [exporting, setExporting] = useState(false);

  // Toast
  const [toast, setToast] = useState<{
    message: string;
    type: "success" | "error";
  } | null>(null);

  const showToast = (message: string, type: "success" | "error" = "success") => {
    setToast({ message, type });
    setTimeout(() => setToast(null), 4000);
  };

  // Load all datasets
  useEffect(() => {
    setLoadingDatasets(true);
    fetch("/datahub/api/datasets")
      .then((res) => res.json())
      .then((data) => setAllDatasets(data.datasets || []))
      .catch((err) => console.error("Error loading datasets:", err))
      .finally(() => setLoadingDatasets(false));
  }, []);

  // Apply from wizard
  const handleWizardApply = useCallback(async (result: WizardResult) => {
    setSelectedLevel(result.level);
    setSimplified(result.simplified);
    setSelections(result.selections);
    setWizardOpen(false);

    setPreviewing(true);
    try {
      const res = await fetch("/datahub/api/join", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          level: result.level,
          simplified: result.simplified,
          selections: result.selections.map((s) => ({
            dataset_id: s.dataset.id,
            columns: s.columns,
            calculatedColumns: s.calculatedColumns,
            temporal_values:
              s.temporalValues.length > 0 ? s.temporalValues : undefined,
          })),
        }),
      });

      if (!res.ok) {
        const err = await res.json();
        throw new Error(err.error || "Eroare la join");
      }

      const geojson = await res.json();
      setPreviewGeojson(geojson);

      // Color by first column of first selection
      const firstSel = result.selections[0];
      if (firstSel) {
        const firstCol = firstSel.columns[0];
        const colMeta = firstSel.dataset.columns.find((c) => c.id === firstCol);
        let propName = firstCol;
        if (firstSel.temporalValues.length > 0 && firstSel.dataset.temporal.type) {
          propName = `${firstCol}_${firstSel.temporalValues[0]}`;
        }
        setColorProperty(propName);
        setColorLabel(colMeta?.name || firstCol);
      }
    } catch (err) {
      console.error("Preview error:", err);
      showToast(
        err instanceof Error ? err.message : "Eroare la previzualizare",
        "error"
      );
    } finally {
      setPreviewing(false);
    }
  }, []);

  // Export
  const handleExport = useCallback(
    async (format: "gpkg" | "geojson" | "kml" | "kmz") => {
      if (!selectedLevel || selections.length === 0) return;
      setExporting(true);
      try {
        const res = await fetch("/datahub/api/export", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            format,
            level: selectedLevel,
            projection,
            style: (format === "kml" || format === "kmz") && colorProperty
              ? {
                  colorProperty,
                  colors: (PALETTES[paletteId] || PALETTES[DEFAULT_PALETTE]).colors,
                }
              : undefined,
            selections: selections.map((s) => ({
              dataset_id: s.dataset.id,
              columns: s.columns,
              calculatedColumns: s.calculatedColumns,
              temporal_values:
                s.temporalValues.length > 0 ? s.temporalValues : undefined,
            })),
          }),
        });

        if (!res.ok) {
          const err = await res.json();
          throw new Error(err.error || "Eroare la export");
        }

        const blob = await res.blob();
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        const dsIds = selections.map((s) => s.dataset.id).join("_");
        a.download = `datahub_${dsIds}_${selectedLevel}.${format}`;
        document.body.appendChild(a);
        a.click();
        document.body.removeChild(a);
        URL.revokeObjectURL(url);
        showToast(`Fișierul ${format.toUpperCase()} descărcat cu succes!`);
      } catch (err) {
        console.error("Export error:", err);
        showToast(
          err instanceof Error ? err.message : "Eroare la export",
          "error"
        );
      } finally {
        setExporting(false);
      }
    },
    [selectedLevel, selections, projection, colorProperty, paletteId]
  );

  const hasSelection = !!selectedLevel && selections.length > 0;
  const levelInfo = GEOMETRY_LEVELS.find((l) => l.id === selectedLevel);
  const totalColumns = selections.reduce((sum, s) => sum + s.columns.length, 0);

  const allColumns = useMemo(() => {
    const cols: Array<{ key: string; label: string }> = [];
    selections.forEach((sel) => {
      sel.columns.forEach((colId) => {
        const colMeta = sel.dataset.columns.find((c) => c.id === colId);
        if (sel.temporalValues.length > 0 && sel.dataset.temporal.type) {
          sel.temporalValues.forEach((tv) => {
            cols.push({
              key: `${colId}_${tv}`,
              label: `${colMeta?.name || colId} (${tv})`,
            });
          });
        } else {
          cols.push({
            key: colId,
            label: colMeta?.name || colId,
          });
        }
      });
      if (sel.calculatedColumns) {
        sel.calculatedColumns.forEach((calc) => {
          if (sel.temporalValues.length > 0 && sel.dataset.temporal.type) {
            sel.temporalValues.forEach((tv) => {
              cols.push({
                key: `${calc.name}_${tv}`,
                label: `${calc.name} (${tv})`,
              });
            });
          } else {
            cols.push({
              key: calc.name,
              label: calc.name,
            });
          }
        });
      }
    });
    return cols;
  }, [selections]);
  // Compute temporal series info for the sparkline chart
  const temporalSeries = useMemo(() => {
    if (!colorProperty) return null;
    // Find the selection that contains this color property
    for (const sel of selections) {
      if (!sel.dataset.temporal.type || sel.temporalValues.length < 2) continue;
      // Check if colorProperty matches baseVar_year pattern for any column
      for (const colId of sel.columns) {
        for (const tv of sel.temporalValues) {
          if (colorProperty === `${colId}_${tv}`) {
            return { baseVar: colId, years: [...sel.temporalValues].sort() };
          }
        }
      }
      // Also check calculated columns
      if (sel.calculatedColumns) {
        for (const calc of sel.calculatedColumns) {
          for (const tv of sel.temporalValues) {
            if (colorProperty === `${calc.name}_${tv}`) {
              return { baseVar: calc.name, years: [...sel.temporalValues].sort() };
            }
          }
        }
      }
    }
    return null;
  }, [colorProperty, selections]);

  // Handle table resize drag
  const handleResizeStart = useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault();
      resizingRef.current = true;
      const startY = e.clientY;
      const startHeight = tableHeight;

      const onMove = (ev: MouseEvent) => {
        if (!resizingRef.current) return;
        const delta = startY - ev.clientY;
        const newH = Math.max(160, Math.min(window.innerHeight * 0.6, startHeight + delta));
        setTableHeight(newH);
      };

      const onUp = () => {
        resizingRef.current = false;
        document.removeEventListener("mousemove", onMove);
        document.removeEventListener("mouseup", onUp);
        document.body.style.cursor = "";
        document.body.style.userSelect = "";
      };

      document.addEventListener("mousemove", onMove);
      document.addEventListener("mouseup", onUp);
      document.body.style.cursor = "ns-resize";
      document.body.style.userSelect = "none";
    },
    [tableHeight]
  );

  return (
    <div className="app-layout">
      {/* Header */}
      <header className="app-header">
        <div className="app-header__logo">
          <div className="app-header__logo-icon">
            <Globe size={16} color="white" />
          </div>
          <span>geo-spatial.org Data Hub</span>
          <span className="app-header__subtitle">
            Date statistice geospațiale
          </span>
        </div>
        <div style={{ display: "flex", gap: 8, alignItems: "center" }}>
          <Link
            href="/explorer"
            className="explorer-nav-btn"
            title="Explorer date tabelar"
          >
            <Table2 size={15} />
            Explorer
          </Link>
          <button
            className="info-btn"
            onClick={() => setInfoOpen(true)}
            title="Despre aplicație"
            aria-label="Informații despre aplicație"
          >
            <Info size={16} />
          </button>
        </div>
      </header>

      {/* Main — map (+ optional table split) */}
      <main className={`app-main${tableOpen && previewGeojson ? " app-main--split" : ""}`} style={{ position: "relative" }}>
        {/* Map area */}
        <div className="app-main__map-area">
          <MapView
            geojson={previewGeojson}
            colorProperty={colorProperty}
            colorLabel={colorLabel}
            displayVariables={allColumns}
            temporalSeries={temporalSeries}
            paletteId={paletteId}
            onPaletteChange={setPaletteId}
          />

          {/* Floating Toolbar — positioned over the map */}
          <div className="map-toolbar">
            {hasSelection ? (
              <div className="map-toolbar__card">
                <div className="map-toolbar__selection">
                  <div className="map-toolbar__label">
                    <MapPin size={12} style={{ display: "inline", verticalAlign: "middle", marginRight: 4 }} />
                    Geometrie
                  </div>
                  <div className="map-toolbar__value">{levelInfo?.name}</div>
                </div>
                <div className="map-toolbar__selection">
                  <div className="map-toolbar__label">
                    <Database size={12} style={{ display: "inline", verticalAlign: "middle", marginRight: 4 }} />
                    Date statistice
                  </div>
                  {selections.map((s) => (
                    <div key={s.dataset.id} className="map-toolbar__value" style={{ fontSize: 13 }}>
                      {s.dataset.name}
                    </div>
                  ))}
                </div>
                <div className="map-toolbar__tags">
                  <span className="badge badge--accent">
                    {totalColumns} variabile
                  </span>
                  <span className="badge badge--accent">
                    {selections.length} set(uri)
                  </span>
                </div>
                <div className="map-toolbar__selection" style={{ marginTop: 8, paddingTop: 8, borderTop: "1px solid var(--color-border)" }}>
                  <div className="map-toolbar__label" style={{ marginBottom: 4 }}>
                    Colorează harta după:
                  </div>
                  <select
                    className="input"
                    style={{ width: "100%", fontSize: 13, padding: "6px 8px" }}
                    value={colorProperty}
                    onChange={(e) => {
                      setColorProperty(e.target.value);
                      const sel = allColumns.find((c) => c.key === e.target.value);
                      if (sel) setColorLabel(sel.label);
                    }}
                  >
                    {allColumns.map((c) => (
                      <option key={c.key} value={c.key}>
                        {c.label}
                      </option>
                    ))}
                  </select>
                </div>
                <div className="map-toolbar__actions" style={{ marginTop: 12 }}>
                  <button className="btn btn--ghost btn--sm" onClick={() => setWizardOpen(true)}>
                    <Pencil size={14} /> Editează
                  </button>
                  <div style={{ display: "flex", gap: 6, alignItems: "center", flexWrap: "wrap" }}>
                    <select
                      className="input"
                      style={{ padding: "4px 8px", fontSize: 12, height: 28, width: 100 }}
                      value={projection}
                      onChange={(e) => setProjection(e.target.value as any)}
                    >
                      <option value="EPSG:3844">Stereo 70</option>
                      <option value="EPSG:4326">WGS84</option>
                    </select>
                    <button
                      className="btn btn--primary btn--sm"
                      disabled={exporting}
                      onClick={() => handleExport("gpkg")}
                      title="Export GeoPackage"
                    >
                      <Download size={14} /> {exporting ? "..." : "GPKG"}
                    </button>
                    <button
                      className="btn btn--primary btn--sm"
                      disabled={exporting}
                      onClick={() => handleExport("kml")}
                      title="Export KML (WGS84)"
                      style={{ background: "var(--color-accent-secondary, #8b5cf6)" }}
                    >
                      <Download size={14} /> {exporting ? "..." : "KML"}
                    </button>
                    <button
                      className="btn btn--primary btn--sm"
                      disabled={exporting}
                      onClick={() => handleExport("kmz")}
                      title="Export KMZ (WGS84, comprimat)"
                      style={{ background: "var(--color-accent-secondary, #8b5cf6)" }}
                    >
                      <Download size={14} /> {exporting ? "..." : "KMZ"}
                    </button>
                  </div>
                </div>
              </div>
            ) : (
              <div className="map-toolbar__card">
                <div style={{ textAlign: "center", padding: "8px 0" }}>
                  <div style={{ fontSize: 28, marginBottom: 8 }}>🗺️</div>
                  <div style={{ fontSize: 14, fontWeight: 600, marginBottom: 6 }}>
                    Configurați vizualizarea
                  </div>
                  <div style={{ fontSize: 12, color: "var(--color-text-muted)", marginBottom: 12 }}>
                    Selectați geometria și datele statistice
                  </div>
                  <button className="btn btn--primary btn--full btn--sm" onClick={() => setWizardOpen(true)}>
                    <Layers size={16} /> Deschide configurarea
                  </button>
                </div>
              </div>
            )}
          </div>

          {/* Table toggle button (shown when data is loaded) */}
          {previewGeojson && (
            <button
              className={`table-toggle-btn${tableOpen ? " table-toggle-btn--active" : ""}`}
              onClick={() => setTableOpen((v) => !v)}
            >
              <Table2 size={15} />
              {tableOpen ? "Ascunde tabelul" : "Tabel date"}
              {tableOpen ? <ChevronDown size={14} /> : <ChevronUp size={14} />}
            </button>
          )}

          {/* Loading overlay */}
          {previewing && (
            <div
              style={{
                position: "absolute",
                inset: 0,
                background: "rgba(0,0,0,0.3)",
                display: "flex",
                alignItems: "center",
                justifyContent: "center",
                zIndex: 5,
              }}
            >
              <div
                style={{
                  background: "var(--color-bg-glass)",
                  backdropFilter: "blur(12px)",
                  borderRadius: "var(--radius-lg)",
                  padding: "24px 40px",
                  display: "flex",
                  alignItems: "center",
                  gap: 12,
                  border: "1px solid var(--color-border)",
                }}
              >
                <span className="spinner" />
                <span style={{ fontSize: 14, fontWeight: 500 }}>
                  Se încarcă datele pe hartă...
                </span>
              </div>
            </div>
          )}
        </div>

        {/* Table panel (split view) */}
        {tableOpen && previewGeojson && (
          <div
            className="app-main__table-area"
            ref={tableAreaRef}
            style={{ height: tableHeight }}
          >
            <div
              className="table-resize-handle"
              onMouseDown={handleResizeStart}
              title="Trage pentru a redimensiona"
            />
            <DataTable
              geojson={previewGeojson}
              columns={allColumns}
            />
          </div>
        )}
      </main>

      {/* Info Modal */}
      {infoOpen && (
        <div className="info-overlay" onClick={() => setInfoOpen(false)}>
          <div className="info-modal" onClick={(e) => e.stopPropagation()}>
            <button
              className="info-modal__close"
              onClick={() => setInfoOpen(false)}
              aria-label="Închide"
            >
              <X size={18} />
            </button>

            <div className="info-modal__header">
              <div className="info-modal__icon">
                <Construction size={22} />
              </div>
              <h2>Data Hub</h2>
              <span className="info-modal__badge">în dezvoltare</span>
            </div>

            <div className="info-modal__body">
              <p>
                Această aplicație este <strong>în curs de implementare</strong>.
                Permite vizualizarea și descărcarea datelor statistice
                geospațiale pentru România, la nivel de județ, regiune de
                dezvoltare și UAT.
              </p>

              <div className="info-modal__section">
                <h3>Sursa datelor</h3>
                <p>
                  Datele statistice provin din baza de date{" "}
                  <strong>TEMPO Online</strong> a Institutului Național de
                  Statistică (INS) și au fost extrase cu ajutorul instrumentului:
                </p>
                <a
                  href="https://github.com/gov2-ro/tempo-ins-dump"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="info-modal__link"
                >
                  <Github size={16} />
                  gov2-ro/tempo-ins-dump
                  <ExternalLink size={12} />
                </a>
              </div>

              <div className="info-modal__section">
                <h3>Open Source</h3>
                <p>
                  Codul sursă al aplicației Data Hub va fi disponibil în
                  curând ca proiect open source.
                </p>
              </div>

              <div className="info-modal__footer">
                <a
                  href="https://geo-spatial.org"
                  target="_blank"
                  rel="noopener noreferrer"
                  className="info-modal__org"
                >
                  geo-spatial.org
                </a>
              </div>
            </div>
          </div>
        </div>
      )}

      {/* Wizard */}
      <DataWizard
        isOpen={wizardOpen}
        onClose={() => setWizardOpen(false)}
        onApply={handleWizardApply}
        allDatasets={allDatasets}
        loadingDatasets={loadingDatasets}
        initialLevel={selectedLevel}
        initialSimplified={simplified}
        initialSelections={selections}
      />

      {/* Toast */}
      {toast && (
        <div className="toast-container">
          <div className="toast">
            <span
              style={{
                color: toast.type === "error" ? "var(--color-error)" : "var(--color-success)",
                fontSize: 16,
              }}
            >
              {toast.type === "error" ? "✕" : "✓"}
            </span>
            {toast.message}
          </div>
        </div>
      )}
    </div>
  );
}
