"use client";

import { useState, useEffect, useCallback, useRef, useDeferredValue } from "react";
import {
  Search,
  Download,
  Layers,
  MapPin,
  Database,
  FileText,
  Map as MapIcon,
} from "lucide-react";
import { Input } from "@/shared/components/ui/input";
import { Badge } from "@/shared/components/ui/badge";
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@/shared/components/ui/tabs";
import type {
  SessionStatus,
  UatEntry,
  SyncRunInfo,
  DbSummary,
} from "./parcel-sync-types";
import { normalizeText } from "./parcel-sync-types";
import { ConnectionPill } from "./connection-pill";
import { EpayConnect, type EpaySessionStatus } from "./epay-connect";
import { SearchTab } from "./tabs/search-tab";
import { LayersTab } from "./tabs/layers-tab";
import { ExportTab } from "./tabs/export-tab";
import { DatabaseTab } from "./tabs/database-tab";
import { CfTab } from "./tabs/cf-tab";
import { MapTab } from "./tabs/map-tab";

/* ------------------------------------------------------------------ */
/*  Main Component                                                     */
/* ------------------------------------------------------------------ */

export function ParcelSyncModule() {
  /* ── Server session ─────────────────────────────────────────── */
  const [session, setSession] = useState<SessionStatus>({
    connected: false,
    activeJobCount: 0,
  });
  const [connecting, setConnecting] = useState(false);
  const [connectionError, setConnectionError] = useState("");
  const autoConnectAttempted = useRef(false);
  const sessionPollRef = useRef<ReturnType<typeof setInterval> | null>(null);

  /* ── UAT autocomplete ───────────────────────────────────────── */
  const [uatData, setUatData] = useState<UatEntry[]>([]);
  const [uatQuery, setUatQuery] = useState("");
  const [uatResults, setUatResults] = useState<UatEntry[]>([]);
  const [showUatResults, setShowUatResults] = useState(false);
  const [siruta, setSiruta] = useState("");
  const [workspacePk, setWorkspacePk] = useState<number | null>(null);
  const uatRef = useRef<HTMLDivElement>(null);

  /* ── Sync status (shared between layers + export tabs) ──────── */
  const [syncLocalCounts, setSyncLocalCounts] = useState<Record<string, number>>({});
  const [syncRuns, setSyncRuns] = useState<SyncRunInfo[]>([]);
  const [syncingSiruta, setSyncingSiruta] = useState("");

  /* ── Global DB summary ──────────────────────────────────────── */
  const [dbSummary, setDbSummary] = useState<DbSummary | null>(null);
  const [dbSummaryLoading, setDbSummaryLoading] = useState(false);

  /* ── Export state (shared flag) ─────────────────────────────── */
  const [exporting, setExporting] = useState(false);

  /* ── ePay status ────────────────────────────────────────────── */
  const [epayStatus, setEpayStatus] = useState<EpaySessionStatus>({ connected: false });

  /* ── Derived ────────────────────────────────────────────────── */
  const sirutaValid = siruta.length > 0 && /^\d+$/.test(siruta);
  const selectedUat = uatData.find((u) => u.siruta === siruta);

  /* ════════════════════════════════════════════════════════════ */
  /*  Session management                                          */
  /* ════════════════════════════════════════════════════════════ */

  const fetchSession = useCallback(async () => {
    try {
      const res = await fetch("/api/eterra/session");
      const data = (await res.json()) as SessionStatus;
      setSession((prev) => {
        if (prev.eterraMaintenance && data.eterraAvailable && !data.eterraMaintenance) {
          autoConnectAttempted.current = false;
        }
        return data;
      });
      if (data.connected) setConnectionError("");
      return data;
    } catch {
      return null;
    }
  }, []);

  useEffect(() => {
    // Load UATs from local DB
    fetch("/api/eterra/uats")
      .then((res) => res.json())
      .then((data: { uats?: UatEntry[]; total?: number }) => {
        if (data.uats && data.uats.length > 0) {
          setUatData(data.uats);
        } else {
          fetch("/api/eterra/uats", { method: "POST" }).catch(() => {});
          fetch("/uat.json")
            .then((res) => res.json())
            .then((fallback: UatEntry[]) => setUatData(fallback))
            .catch(() => {});
        }
      })
      .catch(() => {
        fetch("/uat.json")
          .then((res) => res.json())
          .then((fallback: UatEntry[]) => setUatData(fallback))
          .catch(() => {});
      });

    void fetchSession();
    sessionPollRef.current = setInterval(() => void fetchSession(), 30_000);
    return () => {
      if (sessionPollRef.current) clearInterval(sessionPollRef.current);
    };
  }, [fetchSession]);

  /* ── Reload UATs when session connects ─────────────────────── */
  const prevConnected = useRef(false);
  useEffect(() => {
    if (session.connected && !prevConnected.current) {
      const timer = setTimeout(() => {
        fetch("/api/eterra/uats")
          .then((res) => res.json())
          .then((data: { uats?: UatEntry[] }) => {
            if (data.uats && data.uats.length > 0) setUatData(data.uats);
          })
          .catch(() => {});
      }, 5000);
      return () => clearTimeout(timer);
    }
    prevConnected.current = session.connected;
  }, [session.connected]);

  /* ── UAT autocomplete filter ───────────────────────────────── */
  const deferredUatQuery = useDeferredValue(uatQuery);
  useEffect(() => {
    const raw = deferredUatQuery.trim();
    if (raw.length < 2) {
      setUatResults([]);
      return;
    }
    const isDigit = /^\d+$/.test(raw);
    const query = normalizeText(raw);
    const nameMatches: typeof uatData = [];
    const countyOnlyMatches: typeof uatData = [];
    for (const item of uatData) {
      if (isDigit) {
        if (item.siruta.startsWith(raw)) nameMatches.push(item);
      } else {
        const nameMatch = normalizeText(item.name).includes(query);
        const countyMatch = item.county && normalizeText(item.county).includes(query);
        if (nameMatch) nameMatches.push(item);
        else if (countyMatch) countyOnlyMatches.push(item);
      }
    }
    setUatResults([...nameMatches, ...countyOnlyMatches].slice(0, 12));
  }, [deferredUatQuery, uatData]);

  /* ── Auto-connect on first UAT keystroke ───────────────────── */
  const triggerAutoConnect = useCallback(async () => {
    if (session.connected || connecting || autoConnectAttempted.current) return;
    if (session.eterraMaintenance) return;
    autoConnectAttempted.current = true;
    setConnecting(true);
    setConnectionError("");
    try {
      const res = await fetch("/api/eterra/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "connect" }),
      });
      const data = (await res.json()) as {
        success?: boolean;
        error?: string;
        maintenance?: boolean;
      };
      if (data.success) {
        await fetchSession();
      } else if (data.maintenance) {
        setSession((prev) => ({
          ...prev,
          eterraMaintenance: true,
          eterraAvailable: false,
          eterraHealthMessage: data.error ?? "eTerra în mentenanță",
        }));
        autoConnectAttempted.current = false;
      } else {
        setConnectionError(data.error ?? "Eroare conectare");
      }
    } catch {
      setConnectionError("Eroare rețea");
    }
    setConnecting(false);
  }, [session.connected, session.eterraMaintenance, connecting, fetchSession]);

  /* ── Disconnect ────────────────────────────────────────────── */
  const handleDisconnect = useCallback(async () => {
    try {
      const res = await fetch("/api/eterra/session", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ action: "disconnect" }),
      });
      const data = (await res.json()) as { success?: boolean; error?: string };
      if (data.success) {
        setSession({ connected: false, activeJobCount: 0 });
        autoConnectAttempted.current = false;
      } else {
        setConnectionError(data.error ?? "Nu se poate deconecta");
      }
    } catch {
      setConnectionError("Eroare rețea");
    }
  }, []);

  /* ── Sync status ───────────────────────────────────────────── */
  const fetchSyncStatus = useCallback(async () => {
    if (!siruta) return;
    try {
      const res = await fetch(`/api/eterra/sync-status?siruta=${siruta}`);
      const data = (await res.json()) as {
        localCounts?: Record<string, number>;
        runs?: SyncRunInfo[];
      };
      if (data.localCounts) setSyncLocalCounts(data.localCounts);
      if (data.runs) setSyncRuns(data.runs);
      setSyncingSiruta(siruta);
    } catch {
      // silent
    }
  }, [siruta]);

  useEffect(() => {
    if (siruta && /^\d+$/.test(siruta)) {
      void fetchSyncStatus();
    }
  }, [siruta, fetchSyncStatus]);

  /* ── DB summary ────────────────────────────────────────────── */
  const fetchDbSummary = useCallback(async () => {
    setDbSummaryLoading(true);
    try {
      const res = await fetch("/api/eterra/db-summary");
      const data = (await res.json()) as DbSummary;
      if (data.uats) setDbSummary(data);
    } catch {
      // silent
    }
    setDbSummaryLoading(false);
  }, []);

  useEffect(() => {
    void fetchDbSummary();
  }, [fetchDbSummary]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Render                                                       */
  /* ════════════════════════════════════════════════════════════ */

  return (
    <Tabs defaultValue="search" className="space-y-4">
      {/* ═══════════════════════ Persistent header ═══════════════ */}
      <div className="space-y-3">
        {/* UAT + Connection row */}
        <div className="flex items-start gap-3">
          {/* UAT autocomplete */}
          <div className="relative flex-1 min-w-0" ref={uatRef}>
            <div className="relative">
              <MapPin className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground pointer-events-none" />
              <Input
                id="uat-search"
                placeholder="Selectează UAT — scrie nume sau cod SIRUTA…"
                value={uatQuery}
                onChange={(e) => {
                  setUatQuery(e.target.value);
                  setShowUatResults(true);
                  if (e.target.value.trim().length >= 1) {
                    void triggerAutoConnect();
                  }
                }}
                onFocus={() => setShowUatResults(true)}
                onBlur={() => setTimeout(() => setShowUatResults(false), 150)}
                className="pl-9 font-medium"
                autoComplete="off"
              />
            </div>

            {sirutaValid && (
              <div className="absolute right-2 top-1.5">
                <Badge variant="outline" className="text-[10px] font-mono bg-background">
                  SIRUTA {siruta}
                </Badge>
              </div>
            )}

            {showUatResults && uatResults.length > 0 && (
              <div className="absolute z-50 mt-1 w-full rounded-md border bg-popover shadow-lg max-h-60 overflow-auto">
                {uatResults.map((item) => (
                  <button
                    key={item.siruta}
                    type="button"
                    className="flex w-full items-center justify-between px-3 py-2 text-sm hover:bg-accent transition-colors text-left"
                    onMouseDown={(e) => {
                      e.preventDefault();
                      const label = item.county
                        ? `${item.name} (${item.siruta}), jud. ${item.county}`
                        : `${item.name} (${item.siruta})`;
                      setUatQuery(label);
                      setSiruta(item.siruta);
                      setWorkspacePk(item.workspacePk ?? null);
                      setShowUatResults(false);
                    }}
                  >
                    <span className="flex items-center gap-1.5 min-w-0 flex-wrap">
                      <span className="font-medium">{item.name}</span>
                      <span className="text-muted-foreground">({item.siruta})</span>
                      {item.county && (
                        <span className="text-muted-foreground">
                          {"– "}
                          <span className="font-medium text-foreground/70">
                            jud. {item.county}
                          </span>
                        </span>
                      )}
                      {(item.localFeatures ?? 0) > 0 && (
                        <span className="inline-flex items-center rounded-full bg-emerald-500/15 px-1.5 py-0.5 text-[10px] font-medium text-emerald-600 dark:text-emerald-400 shrink-0">
                          {(item.localFeatures ?? 0).toLocaleString("ro")} local
                        </span>
                      )}
                    </span>
                  </button>
                ))}
              </div>
            )}
          </div>

          {/* Connection pills */}
          <div className="flex items-center gap-2">
            <EpayConnect triggerConnect={sirutaValid} onStatusChange={setEpayStatus} />
            <ConnectionPill
              session={session}
              connecting={connecting}
              connectionError={connectionError}
              onDisconnect={handleDisconnect}
            />
          </div>
        </div>

        {/* Tab bar */}
        <TabsList>
          <TabsTrigger value="search" className="gap-1.5">
            <Search className="h-4 w-4" />
            Căutare Parcele
          </TabsTrigger>
          <TabsTrigger value="layers" className="gap-1.5">
            <Layers className="h-4 w-4" />
            Catalog Layere
          </TabsTrigger>
          <TabsTrigger value="export" className="gap-1.5">
            <Download className="h-4 w-4" />
            Export
          </TabsTrigger>
          <TabsTrigger value="database" className="gap-1.5">
            <Database className="h-4 w-4" />
            Baza de Date
          </TabsTrigger>
          <TabsTrigger value="extracts" className="gap-1.5">
            <FileText className="h-4 w-4" />
            Extrase CF
          </TabsTrigger>
          <TabsTrigger value="map" className="gap-1.5">
            <MapIcon className="h-4 w-4" />
            Harta
          </TabsTrigger>
        </TabsList>
      </div>

      {/* ═══════════════════════ Tab content ═════════════════════ */}

      <TabsContent value="search" className="space-y-4">
        <SearchTab
          siruta={siruta}
          workspacePk={workspacePk}
          sirutaValid={sirutaValid}
          session={session}
          selectedUat={selectedUat}
          epayStatus={epayStatus}
        />
      </TabsContent>

      <TabsContent value="layers" className="space-y-4">
        <LayersTab
          siruta={siruta}
          sirutaValid={sirutaValid}
          session={session}
          syncLocalCounts={syncLocalCounts}
          syncRuns={syncRuns}
          syncingSiruta={syncingSiruta}
          onSyncRefresh={() => void fetchSyncStatus()}
          exporting={exporting}
        />
      </TabsContent>

      <TabsContent value="export" className="space-y-4">
        <ExportTab
          siruta={siruta}
          workspacePk={workspacePk}
          sirutaValid={sirutaValid}
          session={session}
          syncLocalCounts={syncLocalCounts}
          syncRuns={syncRuns}
          syncingSiruta={syncingSiruta}
          onSyncRefresh={() => void fetchSyncStatus()}
          onDbRefresh={() => void fetchDbSummary()}
          exporting={exporting}
          setExporting={setExporting}
        />
      </TabsContent>

      <TabsContent value="database" className="space-y-3">
        <DatabaseTab
          siruta={siruta}
          sirutaValid={sirutaValid}
          dbSummary={dbSummary}
          dbSummaryLoading={dbSummaryLoading}
          onRefresh={() => void fetchDbSummary()}
        />
      </TabsContent>

      <TabsContent value="extracts" className="space-y-4">
        <CfTab />
      </TabsContent>

      <TabsContent value="map" className="space-y-4">
        <MapTab
          siruta={siruta}
          sirutaValid={sirutaValid}
          sessionConnected={session.connected}
          syncLocalCount={Object.values(syncLocalCounts).reduce((s, c) => s + c, 0)}
          onSyncRefresh={() => void fetchSyncStatus()}
        />
      </TabsContent>
    </Tabs>
  );
}
