"use client";

import { useState, useEffect, useCallback, useMemo, useRef } from "react";
import {
  Search,
  Download,
  CheckCircle2,
  XCircle,
  Loader2,
  MapPin,
  Layers,
  Sparkles,
  ChevronDown,
  ChevronUp,
  FileDown,
  LogOut,
  Wifi,
  WifiOff,
  ClipboardCopy,
  Trash2,
  Plus,
  RefreshCw,
  Database,
  HardDrive,
  Clock,
  ArrowDownToLine,
  AlertTriangle,
  BarChart3,
} from "lucide-react";
import { Button } from "@/shared/components/ui/button";
import { Input } from "@/shared/components/ui/input";
import { Label } from "@/shared/components/ui/label";
import { Badge } from "@/shared/components/ui/badge";
import { Card, CardContent } from "@/shared/components/ui/card";
import {
  Tabs,
  TabsContent,
  TabsList,
  TabsTrigger,
} from "@/shared/components/ui/tabs";
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuLabel,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from "@/shared/components/ui/dropdown-menu";
import { cn } from "@/shared/lib/utils";
import {
  LAYER_CATALOG,
  LAYER_CATEGORY_LABELS,
  findLayerById,
  type LayerCategory,
  type LayerCatalogItem,
} from "../services/eterra-layers";
import type { ParcelDetail } from "@/app/api/eterra/search/route";
import type { OwnerSearchResult } from "@/app/api/eterra/search-owner/route";
import { User } from "lucide-react";
import { UatDashboard } from "./uat-dashboard";

/* ------------------------------------------------------------------ */
/*  Types                                                              */
/* ------------------------------------------------------------------ */

type UatEntry = {
  siruta: string;
  name: string;
  county?: string;
  workspacePk?: number;
  localFeatures?: number;
};

type SessionStatus = {
  connected: boolean;
  username?: string;
  connectedAt?: string;
  activeJobCount: number;
  activeJobPhase?: string;
  /** eTerra platform health */
  eterraAvailable?: boolean;
  /** True when eTerra is in maintenance */
  eterraMaintenance?: boolean;
  /** Human-readable health message */
  eterraHealthMessage?: string;
};

type ExportProgress = {
  jobId: string;
  downloaded: number;
  total?: number;
  status: "running" | "done" | "error" | "unknown";
  phase?: string;
  message?: string;
  note?: string;
  phaseCurrent?: number;
  phaseTotal?: number;
};

/* ------------------------------------------------------------------ */
/*  Helpers                                                            */
/* ------------------------------------------------------------------ */

const normalizeText = (text: string) =>
  text
    .normalize("NFD")
    .replace(/[\u0300-\u036f]/g, "")
    .toLowerCase()
    .trim();

function formatDate(iso?: string | null) {
  if (!iso) return "—";
  return new Date(iso).toLocaleDateString("ro-RO", {
    day: "2-digit",
    month: "2-digit",
    year: "numeric",
    hour: "2-digit",
    minute: "2-digit",
  });
}

function formatArea(val?: number | null) {
  if (val == null) return "—";
  return val.toLocaleString("ro-RO", { maximumFractionDigits: 2 }) + " mp";
}

/* ------------------------------------------------------------------ */
/*  Connection Status Pill                                             */
/* ------------------------------------------------------------------ */

function ConnectionPill({
  session,
  connecting,
  connectionError,
  onDisconnect,
}: {
  session: SessionStatus;
  connecting: boolean;
  connectionError: string;
  onDisconnect: () => void;
}) {
  const elapsed = session.connectedAt
    ? Math.floor(
        (Date.now() - new Date(session.connectedAt).getTime()) / 60_000,
      )
    : 0;
  const elapsedLabel =
    elapsed < 1
      ? "acum"
      : elapsed < 60
        ? `${elapsed} min`
        : `${Math.floor(elapsed / 60)}h ${elapsed % 60}m`;

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button
          type="button"
          className={cn(
            "flex items-center gap-2 rounded-full border px-3 py-1.5 text-xs font-medium transition-all",
            "hover:shadow-sm focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
            session.connected
              ? "border-emerald-200 bg-emerald-50/80 text-emerald-700 dark:border-emerald-800 dark:bg-emerald-950/40 dark:text-emerald-400"
              : session.eterraMaintenance
                ? "border-amber-200 bg-amber-50/80 text-amber-600 dark:border-amber-800 dark:bg-amber-950/40 dark:text-amber-400"
                : connectionError
                  ? "border-rose-200 bg-rose-50/80 text-rose-600 dark:border-rose-800 dark:bg-rose-950/40 dark:text-rose-400"
                  : "border-muted-foreground/20 bg-muted/50 text-muted-foreground",
          )}
        >
          {connecting ? (
            <Loader2 className="h-3 w-3 animate-spin" />
          ) : session.connected ? (
            <span className="relative flex h-2 w-2">
              <span className="absolute inline-flex h-full w-full animate-ping rounded-full bg-emerald-400 opacity-75" />
              <span className="relative inline-flex h-2 w-2 rounded-full bg-emerald-500" />
            </span>
          ) : session.eterraMaintenance ? (
            <AlertTriangle className="h-3 w-3" />
          ) : connectionError ? (
            <WifiOff className="h-3 w-3" />
          ) : (
            <Wifi className="h-3 w-3 opacity-50" />
          )}
          <span className="hidden sm:inline">
            {connecting
              ? "Se conectează…"
              : session.connected
                ? "eTerra"
                : session.eterraMaintenance
                  ? "Mentenanță"
                  : connectionError
                    ? "Eroare"
                    : "Deconectat"}
          </span>
        </button>
      </DropdownMenuTrigger>

      <DropdownMenuContent align="end" className="w-72 p-0">
        {/* Status header */}
        <div
          className={cn(
            "px-3 py-2.5 border-b",
            session.connected
              ? "bg-emerald-50/50 dark:bg-emerald-950/20"
              : "bg-muted/30",
          )}
        >
          <div className="flex items-center justify-between">
            <DropdownMenuLabel className="p-0 text-xs font-semibold">
              Conexiune eTerra
            </DropdownMenuLabel>
            {session.connected && (
              <span className="text-[10px] text-emerald-600 dark:text-emerald-400 font-mono">
                {elapsedLabel}
              </span>
            )}
          </div>
          {session.connected && session.username && (
            <p className="text-[11px] text-muted-foreground mt-0.5 truncate">
              {session.username}
            </p>
          )}
          {connectionError && (
            <p className="text-[11px] text-rose-500 mt-0.5">
              {connectionError}
            </p>
          )}
        </div>

        {/* Maintenance banner */}
        {!session.connected && session.eterraMaintenance && (
          <div className="px-3 py-3 text-xs border-b bg-amber-50/50 dark:bg-amber-950/20">
            <div className="flex items-start gap-2">
              <AlertTriangle className="h-3.5 w-3.5 text-amber-500 mt-0.5 shrink-0" />
              <div>
                <p className="font-medium text-amber-700 dark:text-amber-400">
                  eTerra este în mentenanță
                </p>
                <p className="mt-1 text-[11px] text-amber-600/80 dark:text-amber-400/70">
                  Platforma ANCPI nu este disponibilă momentan. Conectarea va fi
                  reactivată automat când serviciul revine online.
                </p>
                {session.eterraHealthMessage && (
                  <p className="mt-1 text-[10px] opacity-60 font-mono">
                    {session.eterraHealthMessage}
                  </p>
                )}
              </div>
            </div>
          </div>
        )}

        {/* Info when not connected (and not in maintenance) */}
        {!session.connected &&
          !connectionError &&
          !session.eterraMaintenance && (
            <div className="px-3 py-3 text-xs text-muted-foreground">
              <p>Conexiunea se face automat când începi să scrii un UAT.</p>
              <p className="mt-1 text-[11px] opacity-70">
                Credențialele sunt preluate din configurarea serverului.
              </p>
            </div>
          )}

        {/* Error detail (only when NOT maintenance — to avoid confusing users) */}
        {!session.connected &&
          connectionError &&
          !session.eterraMaintenance && (
            <div className="px-3 py-3 text-xs text-muted-foreground">
              <p>
                Conexiunea automată a eșuat. Verifică credențialele din
                variabilele de mediu (ETERRA_USERNAME / ETERRA_PASSWORD).
              </p>
            </div>
          )}

        {/* Connected — active jobs info + disconnect */}
        {session.connected && (
          <>
            {session.activeJobCount > 0 && (
              <div className="px-3 py-2 border-b bg-amber-50/50 dark:bg-amber-950/20">
                <p className="text-[11px] text-amber-700 dark:text-amber-400">
                  <span className="font-semibold">
                    {session.activeJobCount} job
                    {session.activeJobCount > 1 ? "-uri" : ""} activ
                    {session.activeJobCount > 1 ? "e" : ""}
                  </span>
                  {session.activeJobPhase && (
                    <span className="opacity-70">
                      {" "}
                      — {session.activeJobPhase}
                    </span>
                  )}
                </p>
              </div>
            )}
            <DropdownMenuSeparator className="m-0" />
            <div className="p-1.5">
              <button
                type="button"
                className="flex w-full items-center gap-2 rounded-sm px-2 py-1.5 text-xs text-muted-foreground hover:bg-muted hover:text-foreground transition-colors"
                onClick={onDisconnect}
              >
                <LogOut className="h-3 w-3" />
                Deconectare
              </button>
            </div>
          </>
        )}
      </DropdownMenuContent>
    </DropdownMenu>
  );
}

/* ------------------------------------------------------------------ */
/*  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);

  /* ── Export state ────────────────────────────────────────────── */
  const [exportJobId, setExportJobId] = useState<string | null>(null);
  const [exportProgress, setExportProgress] = useState<ExportProgress | null>(
    null,
  );
  const [phaseTrail, setPhaseTrail] = useState<string[]>([]);
  const [exporting, setExporting] = useState(false);
  const pollingRef = useRef<ReturnType<typeof setInterval> | null>(null);

  /* ── Layer catalog UI ───────────────────────────────────────── */
  const [expandedCategories, setExpandedCategories] = useState<
    Record<string, boolean>
  >({});
  const [downloadingLayer, setDownloadingLayer] = useState<string | null>(null);
  const [layerCounts, setLayerCounts] = useState<
    Record<string, { count: number; error?: string }>
  >({});
  const [countingLayers, setCountingLayers] = useState(false);
  const [layerCountSiruta, setLayerCountSiruta] = useState(""); // siruta for which counts were fetched
  const [layerHistory, setLayerHistory] = useState<
    {
      layerId: string;
      label: string;
      count: number;
      time: string;
      siruta: string;
    }[]
  >([]);

  /* ── Sync status ────────────────────────────────────────────── */
  type SyncRunInfo = {
    id: string;
    layerId: string;
    status: string;
    totalRemote: number;
    totalLocal: number;
    newFeatures: number;
    removedFeatures: number;
    startedAt: string;
    completedAt?: string;
  };
  const [syncLocalCounts, setSyncLocalCounts] = useState<
    Record<string, number>
  >({});
  const [syncRuns, setSyncRuns] = useState<SyncRunInfo[]>([]);
  const [syncingSiruta, setSyncingSiruta] = useState("");
  const [syncingLayer, setSyncingLayer] = useState<string | null>(null);
  const [syncProgress, setSyncProgress] = useState("");
  const [exportingLocal, setExportingLocal] = useState(false);
  const refreshSyncRef = useRef<(() => void) | null>(null);

  /* ── Global DB summary (all UATs) ────────────────────────────── */
  type DbUatSummary = {
    siruta: string;
    uatName: string;
    county: string | null;
    layers: {
      layerId: string;
      count: number;
      enrichedCount: number;
      noGeomCount: number;
      lastSynced: string | null;
    }[];
    totalFeatures: number;
    totalEnriched: number;
    totalNoGeom: number;
  };
  type DbSummary = {
    uats: DbUatSummary[];
    totalFeatures: number;
    totalUats: number;
  };
  const [dbSummary, setDbSummary] = useState<DbSummary | null>(null);
  const [dbSummaryLoading, setDbSummaryLoading] = useState(false);

  /* ── PostGIS setup ───────────────────────────────────────────── */
  const [postgisRunning, setPostgisRunning] = useState(false);
  const [postgisResult, setPostgisResult] = useState<{
    success: boolean;
    message?: string;
    details?: Record<string, unknown>;
    error?: string;
  } | null>(null);

  /* ── Parcel search tab ──────────────────────────────────────── */
  const [searchMode, setSearchMode] = useState<"cadastral" | "owner">(
    "cadastral",
  );
  const [searchResults, setSearchResults] = useState<ParcelDetail[]>([]);
  const [searchList, setSearchList] = useState<ParcelDetail[]>([]);
  const [featuresSearch, setFeaturesSearch] = useState("");
  const [loadingFeatures, setLoadingFeatures] = useState(false);
  const [searchError, setSearchError] = useState("");
  /* owner search */
  const [ownerSearch, setOwnerSearch] = useState("");
  const [ownerResults, setOwnerResults] = useState<OwnerSearchResult[]>([]);
  const [ownerLoading, setOwnerLoading] = useState(false);
  const [ownerError, setOwnerError] = useState("");
  const [ownerNote, setOwnerNote] = useState("");
  /* dashboard */
  const [dashboardSiruta, setDashboardSiruta] = useState<string | null>(null);

  /* ── No-geometry import option ──────────────────────────────── */
  const [includeNoGeom, setIncludeNoGeom] = useState(false);
  const [noGeomScanning, setNoGeomScanning] = useState(false);
  const [noGeomScan, setNoGeomScan] = useState<{
    totalImmovables: number;
    withGeometry: number;
    remoteGisCount: number;
    remoteCladiriCount: number;
    noGeomCount: number;
    matchedByRef: number;
    matchedById: number;
    qualityBreakdown: {
      withCadRef: number;
      withPaperCad: number;
      withPaperLb: number;
      withLandbook: number;
      withArea: number;
      withActiveStatus: number;
      useful: number;
      empty: number;
    };
    localDbTotal: number;
    localDbWithGeom: number;
    localDbNoGeom: number;
    localDbEnriched: number;
    localDbEnrichedComplete: number;
    localSyncFresh: boolean;
    scannedAt: string;
  } | null>(null);
  const [noGeomScanSiruta, setNoGeomScanSiruta] = useState(""); // siruta for which scan was done

  /* ── Background sync state ──────────────────────────────────── */
  const [bgJobId, setBgJobId] = useState<string | null>(null);
  const [bgProgress, setBgProgress] = useState<ExportProgress | null>(null);
  const [bgPhaseTrail, setBgPhaseTrail] = useState<string[]>([]);
  const bgPollingRef = useRef<ReturnType<typeof setInterval> | null>(null);
  const [downloadingFromDb, setDownloadingFromDb] = useState(false);

  /* ════════════════════════════════════════════════════════════ */
  /*  Load UAT data  +  check server session on mount             */
  /* ════════════════════════════════════════════════════════════ */

  const fetchSession = useCallback(async () => {
    try {
      const res = await fetch("/api/eterra/session");
      const data = (await res.json()) as SessionStatus;
      setSession((prev) => {
        // If eTerra was in maintenance but is now back online, reset auto-connect
        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 (fast — no eTerra needed)
    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 {
          // DB empty — seed from uat.json via POST, then load from uat.json
          fetch("/api/eterra/uats", { method: "POST" }).catch(() => {});
          fetch("/uat.json")
            .then((res) => res.json())
            .then((fallback: UatEntry[]) => setUatData(fallback))
            .catch(() => {});
        }
      })
      .catch(() => {
        // API failed — fall back to static uat.json
        fetch("/uat.json")
          .then((res) => res.json())
          .then((fallback: UatEntry[]) => setUatData(fallback))
          .catch(() => {});
      });

    // Check existing server session on mount
    void fetchSession();

    // Poll session every 30s to stay in sync with other clients
    sessionPollRef.current = setInterval(() => void fetchSession(), 30_000);
    return () => {
      if (sessionPollRef.current) clearInterval(sessionPollRef.current);
    };
  }, [fetchSession]);

  /* ── Fetch global 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]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Reload UAT data when session connects (county data may     */
  /*  have been populated by the login flow)                      */
  /* ════════════════════════════════════════════════════════════ */

  const prevConnected = useRef(false);

  useEffect(() => {
    if (session.connected && !prevConnected.current) {
      // Just connected — reload UATs after a short delay to let
      // the server-side county refresh finish
      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                                     */
  /* ════════════════════════════════════════════════════════════ */

  useEffect(() => {
    const raw = uatQuery.trim();
    if (raw.length < 2) {
      setUatResults([]);
      return;
    }
    const isDigit = /^\d+$/.test(raw);
    const query = normalizeText(raw);
    const results = uatData
      .filter((item) => {
        if (isDigit) return item.siruta.startsWith(raw);
        // Match UAT name or county name
        if (normalizeText(item.name).includes(query)) return true;
        if (item.county && normalizeText(item.county).includes(query))
          return true;
        return false;
      })
      .slice(0, 12);
    setUatResults(results);
  }, [uatQuery, uatData]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Auto-connect: trigger on first UAT keystroke                 */
  /* ════════════════════════════════════════════════════════════ */

  const triggerAutoConnect = useCallback(async () => {
    if (session.connected || connecting || autoConnectAttempted.current) return;
    // Don't attempt login when eTerra is in maintenance
    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) {
        // eTerra is in maintenance — set flag, DON'T show as connection error
        setSession((prev) => ({
          ...prev,
          eterraMaintenance: true,
          eterraAvailable: false,
          eterraHealthMessage: data.error ?? "eTerra în mentenanță",
        }));
        // Allow retry later when maintenance ends
        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 {
        // Jobs are running — show warning
        setConnectionError(data.error ?? "Nu se poate deconecta");
      }
    } catch {
      setConnectionError("Eroare rețea");
    }
  }, []);

  /* ════════════════════════════════════════════════════════════ */
  /*  Progress polling                                             */
  /* ════════════════════════════════════════════════════════════ */

  const startPolling = useCallback((jid: string) => {
    if (pollingRef.current) clearInterval(pollingRef.current);
    pollingRef.current = setInterval(async () => {
      try {
        const res = await fetch(
          `/api/eterra/progress?jobId=${encodeURIComponent(jid)}`,
        );
        const data = (await res.json()) as ExportProgress;
        setExportProgress(data);
        if (data.phase) {
          setPhaseTrail((prev) => {
            if (prev[prev.length - 1] === data.phase) return prev;
            return [...prev, data.phase!];
          });
        }
        if (data.status === "done" || data.status === "error") {
          if (pollingRef.current) {
            clearInterval(pollingRef.current);
            pollingRef.current = null;
          }
        }
      } catch {
        /* ignore polling errors */
      }
    }, 1000);
  }, []);

  useEffect(() => {
    return () => {
      if (pollingRef.current) clearInterval(pollingRef.current);
    };
  }, []);

  /* ════════════════════════════════════════════════════════════ */
  /*  Export bundle (base / magic)                                 */
  /* ════════════════════════════════════════════════════════════ */

  const handleExportBundle = useCallback(
    async (mode: "base" | "magic") => {
      if (!siruta || exporting) return;
      const jobId = crypto.randomUUID();
      setExportJobId(jobId);
      setExportProgress(null);
      setPhaseTrail([]);
      setExporting(true);

      startPolling(jobId);

      try {
        const res = await fetch("/api/eterra/export-bundle", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta,
            jobId,
            mode,
            includeNoGeometry: includeNoGeom,
          }),
        });

        if (!res.ok) {
          const err = (await res.json().catch(() => ({}))) as {
            error?: string;
          };
          throw new Error(err.error ?? `HTTP ${res.status}`);
        }

        const blob = await res.blob();
        const cd = res.headers.get("Content-Disposition") ?? "";
        const match = /filename="?([^"]+)"?/.exec(cd);
        const filename =
          match?.[1] ??
          (mode === "magic"
            ? `eterra_uat_${siruta}_magic.zip`
            : `eterra_uat_${siruta}_terenuri_cladiri.zip`);

        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(url);

        // Mark progress as done after successful download
        setExportProgress((prev) =>
          prev
            ? {
                ...prev,
                status: "done",
                phase: "Finalizat",
                downloaded: prev.total ?? 100,
                total: prev.total ?? 100,
                message: `Descărcare completă — ${filename}`,
                note: undefined,
              }
            : null,
        );
      } catch (error) {
        const msg = error instanceof Error ? error.message : "Eroare export";
        setExportProgress((prev) =>
          prev
            ? { ...prev, status: "error", message: msg }
            : {
                jobId,
                downloaded: 0,
                status: "error",
                message: msg,
              },
        );
      }

      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
      setExporting(false);
      // Refresh sync status — data was synced to DB
      refreshSyncRef.current?.();
    },
    [siruta, exporting, startPolling, includeNoGeom],
  );

  /* ════════════════════════════════════════════════════════════ */
  /*  No-geometry scan                                             */
  /* ════════════════════════════════════════════════════════════ */

  const handleNoGeomScan = useCallback(
    async (targetSiruta?: string) => {
      const s = targetSiruta ?? siruta;
      if (!s) return;
      setNoGeomScanning(true);
      setNoGeomScan(null);
      setNoGeomScanSiruta(s);
      const emptyQuality = {
        withCadRef: 0,
        withPaperCad: 0,
        withPaperLb: 0,
        withLandbook: 0,
        withArea: 0,
        withActiveStatus: 0,
        useful: 0,
        empty: 0,
      };
      const emptyResult = {
        totalImmovables: 0,
        withGeometry: 0,
        remoteGisCount: 0,
        remoteCladiriCount: 0,
        noGeomCount: 0,
        matchedByRef: 0,
        matchedById: 0,
        qualityBreakdown: emptyQuality,
        localDbTotal: 0,
        localDbWithGeom: 0,
        localDbNoGeom: 0,
        localDbEnriched: 0,
        localDbEnrichedComplete: 0,
        localSyncFresh: false,
        scannedAt: "",
      };
      try {
        // 2min timeout — scan is informational, should not block the page
        const scanAbort = new AbortController();
        const scanTimer = setTimeout(() => scanAbort.abort(), 120_000);
        const res = await fetch("/api/eterra/no-geom-scan", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta: s,
            workspacePk: workspacePk ?? undefined,
          }),
          signal: scanAbort.signal,
        });
        clearTimeout(scanTimer);
        const data = (await res.json()) as Record<string, unknown>;
        if (data.error) {
          console.warn("[no-geom-scan]", data.error);
          setNoGeomScan(emptyResult);
        } else {
          const qb = (data.qualityBreakdown ?? {}) as Record<string, unknown>;
          setNoGeomScan({
            totalImmovables: Number(data.totalImmovables ?? 0),
            withGeometry: Number(data.withGeometry ?? 0),
            remoteGisCount: Number(data.remoteGisCount ?? 0),
            remoteCladiriCount: Number(data.remoteCladiriCount ?? 0),
            noGeomCount: Number(data.noGeomCount ?? 0),
            matchedByRef: Number(data.matchedByRef ?? 0),
            matchedById: Number(data.matchedById ?? 0),
            qualityBreakdown: {
              withCadRef: Number(qb.withCadRef ?? 0),
              withPaperCad: Number(qb.withPaperCad ?? 0),
              withPaperLb: Number(qb.withPaperLb ?? 0),
              withLandbook: Number(qb.withLandbook ?? 0),
              withArea: Number(qb.withArea ?? 0),
              withActiveStatus: Number(qb.withActiveStatus ?? 0),
              useful: Number(qb.useful ?? 0),
              empty: Number(qb.empty ?? 0),
            },
            localDbTotal: Number(data.localDbTotal ?? 0),
            localDbWithGeom: Number(data.localDbWithGeom ?? 0),
            localDbNoGeom: Number(data.localDbNoGeom ?? 0),
            localDbEnriched: Number(data.localDbEnriched ?? 0),
            localDbEnrichedComplete: Number(data.localDbEnrichedComplete ?? 0),
            localSyncFresh: Boolean(data.localSyncFresh),
            scannedAt: String(data.scannedAt ?? new Date().toISOString()),
          });
        }
      } catch (err) {
        // Distinguish timeout from other errors for the user
        const isTimeout =
          err instanceof DOMException && err.name === "AbortError";
        if (isTimeout) {
          console.warn(
            "[no-geom-scan] Timeout after 2 min — server eTerra lent",
          );
        }
        setNoGeomScan({
          ...emptyResult,
          scannedAt: isTimeout ? "timeout" : "",
        });
      }
      setNoGeomScanning(false);
    },
    [siruta, workspacePk],
  );

  // Auto-scan for no-geometry parcels when UAT is selected + connected
  const noGeomAutoScanRef = useRef("");
  useEffect(() => {
    if (!siruta || !session.connected) return;
    // Don't re-scan if we already scanned (or are scanning) this siruta
    if (noGeomAutoScanRef.current === siruta) return;
    noGeomAutoScanRef.current = siruta;
    void handleNoGeomScan(siruta);
  }, [siruta, session.connected, handleNoGeomScan]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Layer feature counts                                         */
  /* ════════════════════════════════════════════════════════════ */

  // Load history from localStorage on mount
  useEffect(() => {
    try {
      const raw = localStorage.getItem("parcel-sync:layer-history");
      if (raw) {
        const parsed = JSON.parse(raw) as typeof layerHistory;
        // Only keep today's entries
        const today = new Date().toISOString().slice(0, 10);
        const todayEntries = parsed.filter(
          (e) => e.time.slice(0, 10) === today,
        );
        setLayerHistory(todayEntries);
      }
    } catch {
      // ignore
    }
  }, []);

  const fetchLayerCounts = useCallback(async () => {
    if (!siruta || countingLayers) return;
    setCountingLayers(true);
    try {
      const res = await fetch("/api/eterra/layers/summary", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ siruta }),
      });
      const data = (await res.json()) as {
        counts?: Record<string, { count: number; error?: string }>;
        error?: string;
      };
      if (data.counts) {
        setLayerCounts(data.counts);
        setLayerCountSiruta(siruta);

        // Save non-zero counts to history
        const now = new Date().toISOString();
        const today = now.slice(0, 10);
        const newEntries: typeof layerHistory = [];
        for (const [layerId, info] of Object.entries(data.counts)) {
          if (info.count > 0) {
            const layer = LAYER_CATALOG.find((l) => l.id === layerId);
            newEntries.push({
              layerId,
              label: layer?.label ?? layerId,
              count: info.count,
              time: now,
              siruta,
            });
          }
        }
        setLayerHistory((prev) => {
          // Keep today's entries only, add new batch
          const kept = prev.filter(
            (e) => e.time.slice(0, 10) === today && e.siruta !== siruta,
          );
          const merged = [...kept, ...newEntries];
          try {
            localStorage.setItem(
              "parcel-sync:layer-history",
              JSON.stringify(merged),
            );
          } catch {
            // quota
          }
          return merged;
        });
      }
    } catch {
      // silent
    }
    setCountingLayers(false);
  }, [siruta, countingLayers]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Sync status — load local feature counts for current UAT      */
  /* ════════════════════════════════════════════════════════════ */

  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]);

  // Keep ref in sync so callbacks defined earlier can trigger refresh
  refreshSyncRef.current = () => void fetchSyncStatus();

  // Auto-fetch sync status when siruta changes
  useEffect(() => {
    if (siruta && /^\d+$/.test(siruta)) {
      void fetchSyncStatus();
    }
  }, [siruta, fetchSyncStatus]);

  const handleSyncLayer = useCallback(
    async (layerId: string) => {
      if (!siruta || syncingLayer) return;
      setSyncingLayer(layerId);
      setSyncProgress("Sincronizare pornită…");
      try {
        const res = await fetch("/api/eterra/sync", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta,
            layerId,
            jobId: crypto.randomUUID(),
          }),
        });
        const data = (await res.json()) as {
          status?: string;
          newFeatures?: number;
          removedFeatures?: number;
          totalLocal?: number;
          error?: string;
        };
        if (data.error) {
          setSyncProgress(`Eroare: ${data.error}`);
        } else {
          setSyncProgress(
            `Finalizat — ${data.newFeatures ?? 0} noi, ${data.removedFeatures ?? 0} șterse, ${data.totalLocal ?? 0} total local`,
          );
          // Refresh sync status
          await fetchSyncStatus();
        }
      } catch {
        setSyncProgress("Eroare rețea");
      }
      // Clear progress after 8s
      setTimeout(() => {
        setSyncingLayer(null);
        setSyncProgress("");
      }, 8_000);
    },
    [siruta, syncingLayer, fetchSyncStatus],
  );

  const handleExportLocal = useCallback(
    async (layerIds?: string[]) => {
      if (!siruta || exportingLocal) return;
      setExportingLocal(true);
      try {
        const res = await fetch("/api/eterra/export-local", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta,
            ...(layerIds ? { layerIds } : { allLayers: true }),
          }),
        });
        if (!res.ok) {
          const err = (await res.json().catch(() => ({}))) as {
            error?: string;
          };
          throw new Error(err.error ?? `HTTP ${res.status}`);
        }
        const blob = await res.blob();
        const cd = res.headers.get("Content-Disposition") ?? "";
        const match = /filename="?([^"]+)"?/.exec(cd);
        const filename =
          match?.[1] ??
          `eterra_local_${siruta}.${layerIds?.length === 1 ? "gpkg" : "zip"}`;
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(url);
      } catch (error) {
        const msg = error instanceof Error ? error.message : "Eroare export";
        setSyncProgress(msg);
        setTimeout(() => setSyncProgress(""), 5_000);
      }
      setExportingLocal(false);
    },
    [siruta, exportingLocal],
  );

  /* ════════════════════════════════════════════════════════════ */
  /*  Background sync — fire-and-forget server-side processing     */
  /* ════════════════════════════════════════════════════════════ */

  const startBgPolling = useCallback(
    (jid: string) => {
      if (bgPollingRef.current) clearInterval(bgPollingRef.current);
      bgPollingRef.current = setInterval(async () => {
        try {
          const res = await fetch(
            `/api/eterra/progress?jobId=${encodeURIComponent(jid)}`,
          );
          const data = (await res.json()) as ExportProgress;
          setBgProgress(data);
          if (data.phase) {
            setBgPhaseTrail((prev) => {
              if (prev[prev.length - 1] === data.phase) return prev;
              return [...prev, data.phase!];
            });
          }
          if (data.status === "done" || data.status === "error") {
            if (bgPollingRef.current) {
              clearInterval(bgPollingRef.current);
              bgPollingRef.current = null;
            }
            // Clean localStorage marker
            try {
              localStorage.removeItem("parcel-sync:bg-job");
            } catch {
              /* */
            }
            // Refresh sync status and DB summary
            refreshSyncRef.current?.();
            void fetchDbSummary();
          }
        } catch {
          /* ignore polling errors */
        }
      }, 1500);
    },
    [fetchDbSummary],
  );

  // Cleanup bg polling on unmount
  useEffect(() => {
    return () => {
      if (bgPollingRef.current) clearInterval(bgPollingRef.current);
    };
  }, []);

  // Recover background job from localStorage on mount
  useEffect(() => {
    try {
      const raw = localStorage.getItem("parcel-sync:bg-job");
      if (!raw) return;
      const saved = JSON.parse(raw) as {
        jobId: string;
        siruta: string;
        startedAt: string;
      };
      // Ignore jobs older than 8 hours
      const age = Date.now() - new Date(saved.startedAt).getTime();
      if (age > 8 * 60 * 60 * 1000) {
        localStorage.removeItem("parcel-sync:bg-job");
        return;
      }
      // Check if job is still running
      void (async () => {
        try {
          const res = await fetch(
            `/api/eterra/progress?jobId=${encodeURIComponent(saved.jobId)}`,
          );
          const data = (await res.json()) as ExportProgress;
          if (data.status === "running") {
            setBgJobId(saved.jobId);
            setBgProgress(data);
            if (data.phase) setBgPhaseTrail([data.phase]);
            startBgPolling(saved.jobId);
          } else if (data.status === "done") {
            setBgJobId(saved.jobId);
            setBgProgress(data);
            if (data.phase) setBgPhaseTrail(["Sincronizare completă"]);
            localStorage.removeItem("parcel-sync:bg-job");
          } else {
            localStorage.removeItem("parcel-sync:bg-job");
          }
        } catch {
          localStorage.removeItem("parcel-sync:bg-job");
        }
      })();
    } catch {
      /* */
    }
  }, [startBgPolling]);

  const handleSyncBackground = useCallback(
    async (mode: "base" | "magic") => {
      if (!siruta || exporting) return;
      try {
        const res = await fetch("/api/eterra/sync-background", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta,
            mode,
            includeNoGeometry: includeNoGeom,
          }),
        });
        const data = (await res.json()) as { jobId?: string; error?: string };
        if (!res.ok || data.error) {
          setSyncProgress(data.error ?? `Eroare ${res.status}`);
          setTimeout(() => setSyncProgress(""), 5_000);
          return;
        }
        const jid = data.jobId!;
        setBgJobId(jid);
        setBgProgress({
          jobId: jid,
          downloaded: 0,
          total: 100,
          status: "running",
          phase: "Pornire sincronizare fundal",
        });
        setBgPhaseTrail(["Pornire sincronizare fundal"]);
        // Persist in localStorage so we can recover on page refresh
        try {
          localStorage.setItem(
            "parcel-sync:bg-job",
            JSON.stringify({
              jobId: jid,
              siruta,
              startedAt: new Date().toISOString(),
            }),
          );
        } catch {
          /* */
        }
        startBgPolling(jid);
      } catch (error) {
        const msg = error instanceof Error ? error.message : "Eroare rețea";
        setSyncProgress(msg);
        setTimeout(() => setSyncProgress(""), 5_000);
      }
    },
    [siruta, exporting, includeNoGeom, startBgPolling],
  );

  const handleDownloadFromDb = useCallback(
    async (mode: "base" | "magic") => {
      if (!siruta || downloadingFromDb) return;
      setDownloadingFromDb(true);
      try {
        const res = await fetch("/api/eterra/export-local", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ siruta, mode }),
        });
        if (!res.ok) {
          const err = (await res.json().catch(() => ({}))) as {
            error?: string;
          };
          throw new Error(err.error ?? `HTTP ${res.status}`);
        }
        const blob = await res.blob();
        const cd = res.headers.get("Content-Disposition") ?? "";
        const match = /filename="?([^"]+)"?/.exec(cd);
        const filename = match?.[1] ?? `eterra_uat_${siruta}_${mode}_local.zip`;
        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(url);
      } catch (error) {
        const msg =
          error instanceof Error ? error.message : "Eroare descărcare";
        setSyncProgress(msg);
        setTimeout(() => setSyncProgress(""), 5_000);
      }
      setDownloadingFromDb(false);
    },
    [siruta, downloadingFromDb],
  );

  // Sync multiple layers sequentially (for "sync all" / "sync category")
  const [syncQueue, setSyncQueue] = useState<string[]>([]);
  const syncQueueRef = useRef<string[]>([]);

  const handleSyncMultiple = useCallback(
    async (layerIds: string[]) => {
      if (!siruta || syncingLayer || syncQueue.length > 0) return;
      syncQueueRef.current = [...layerIds];
      setSyncQueue([...layerIds]);

      for (const layerId of layerIds) {
        setSyncingLayer(layerId);
        setSyncProgress(
          `Sincronizare ${LAYER_CATALOG.find((l) => l.id === layerId)?.label ?? layerId}…`,
        );
        try {
          const res = await fetch("/api/eterra/sync", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({
              siruta,
              layerId,
              jobId: crypto.randomUUID(),
            }),
          });
          const data = (await res.json()) as {
            error?: string;
            newFeatures?: number;
            removedFeatures?: number;
            totalLocal?: number;
          };
          if (data.error) {
            setSyncProgress(`Eroare: ${data.error}`);
          }
        } catch {
          setSyncProgress("Eroare rețea");
        }
        // Remove from queue
        syncQueueRef.current = syncQueueRef.current.filter(
          (id) => id !== layerId,
        );
        setSyncQueue([...syncQueueRef.current]);
      }
      // Done — refresh status
      await fetchSyncStatus();
      setSyncingLayer(null);
      setSyncProgress("");
      setSyncQueue([]);
      syncQueueRef.current = [];
    },
    [siruta, syncingLayer, syncQueue.length, fetchSyncStatus],
  );

  /* ════════════════════════════════════════════════════════════ */
  /*  PostGIS setup (one-time)                                     */
  /* ════════════════════════════════════════════════════════════ */

  const handleSetupPostgis = useCallback(async () => {
    if (postgisRunning) return;
    setPostgisRunning(true);
    setPostgisResult(null);
    try {
      const res = await fetch("/api/eterra/setup-postgis", { method: "POST" });
      const json = await res.json();
      setPostgisResult(json as typeof postgisResult);
    } catch (error) {
      const msg = error instanceof Error ? error.message : "Eroare setup";
      setPostgisResult({ success: false, error: msg });
    }
    setPostgisRunning(false);
  }, [postgisRunning, postgisResult]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Export individual layer                                      */
  /* ════════════════════════════════════════════════════════════ */

  const handleExportLayer = useCallback(
    async (layerId: string) => {
      if (!siruta || downloadingLayer) return;
      setDownloadingLayer(layerId);
      const jobId = crypto.randomUUID();
      setExportJobId(jobId);
      setExportProgress(null);
      setPhaseTrail([]);

      startPolling(jobId);

      try {
        const res = await fetch("/api/eterra/export-layer-gpkg", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({
            siruta,
            layerId,
            jobId,
          }),
        });

        if (!res.ok) {
          const err = (await res.json().catch(() => ({}))) as {
            error?: string;
          };
          throw new Error(err.error ?? `HTTP ${res.status}`);
        }

        const blob = await res.blob();
        const cd = res.headers.get("Content-Disposition") ?? "";
        const match = /filename="?([^"]+)"?/.exec(cd);
        const filename = match?.[1] ?? `eterra_uat_${siruta}_${layerId}.gpkg`;

        const url = URL.createObjectURL(blob);
        const a = document.createElement("a");
        a.href = url;
        a.download = filename;
        document.body.appendChild(a);
        a.click();
        a.remove();
        URL.revokeObjectURL(url);

        // Mark progress as done after successful download
        setExportProgress((prev) =>
          prev
            ? {
                ...prev,
                status: "done",
                phase: "Finalizat",
                downloaded: prev.total ?? 100,
                total: prev.total ?? 100,
                message: `Descărcare completă — ${filename}`,
                note: undefined,
              }
            : null,
        );
      } catch (error) {
        const msg = error instanceof Error ? error.message : "Eroare export";
        setExportProgress((prev) =>
          prev
            ? { ...prev, status: "error", message: msg }
            : {
                jobId,
                downloaded: 0,
                status: "error",
                message: msg,
              },
        );
      }

      if (pollingRef.current) {
        clearInterval(pollingRef.current);
        pollingRef.current = null;
      }
      setDownloadingLayer(null);
      // Refresh sync status — layer was synced to DB
      refreshSyncRef.current?.();
    },
    [siruta, downloadingLayer, startPolling],
  );

  /* ════════════════════════════════════════════════════════════ */
  /*  Search parcels by cadastral number (eTerra app API)          */
  /* ════════════════════════════════════════════════════════════ */

  const handleSearch = useCallback(async () => {
    if (!siruta || !/^\d+$/.test(siruta)) return;
    if (!featuresSearch.trim()) {
      setSearchResults([]);
      setSearchError("");
      return;
    }
    setLoadingFeatures(true);
    setSearchError("");
    try {
      const res = await fetch("/api/eterra/search", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          siruta,
          search: featuresSearch.trim(),
          ...(workspacePk ? { workspacePk } : {}),
        }),
      });
      const data = (await res.json()) as {
        results?: ParcelDetail[];
        total?: number;
        error?: string;
      };
      if (data.error) {
        setSearchResults([]);
        setSearchError(data.error);
      } else {
        setSearchResults(data.results ?? []);
        setSearchError("");
      }
    } catch {
      setSearchError("Eroare de rețea.");
    }
    setLoadingFeatures(false);
  }, [siruta, featuresSearch, workspacePk]);

  // No auto-search — user clicks button or presses Enter
  const handleSearchKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter") {
        e.preventDefault();
        void handleSearch();
      }
    },
    [handleSearch],
  );

  /* ── Owner search handler ────────────────────────────────── */
  const handleOwnerSearch = useCallback(async () => {
    if (!siruta || !/^\d+$/.test(siruta)) return;
    if (!ownerSearch.trim() || ownerSearch.trim().length < 2) {
      setOwnerError("Minim 2 caractere.");
      return;
    }
    setOwnerLoading(true);
    setOwnerError("");
    setOwnerNote("");
    try {
      const res = await fetch("/api/eterra/search-owner", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          siruta,
          ownerName: ownerSearch.trim(),
          ...(workspacePk ? { workspacePk } : {}),
        }),
      });
      const data = (await res.json()) as {
        results?: OwnerSearchResult[];
        total?: number;
        dbSearched?: boolean;
        eterraSearched?: boolean;
        eterraNote?: string;
        error?: string;
      };
      if (data.error) {
        setOwnerResults([]);
        setOwnerError(data.error);
      } else {
        setOwnerResults(data.results ?? []);
        const notes: string[] = [];
        if (data.dbSearched) notes.push("DB local");
        if (data.eterraSearched) notes.push("eTerra API");
        if (data.eterraNote) notes.push(data.eterraNote);
        setOwnerNote(
          notes.length > 0
            ? `Surse: ${notes.join(" + ")}${data.total ? ` · ${data.total} rezultate` : ""}`
            : "",
        );
      }
    } catch {
      setOwnerError("Eroare de rețea.");
    }
    setOwnerLoading(false);
  }, [siruta, ownerSearch, workspacePk]);

  const handleOwnerKeyDown = useCallback(
    (e: React.KeyboardEvent) => {
      if (e.key === "Enter") {
        e.preventDefault();
        void handleOwnerSearch();
      }
    },
    [handleOwnerSearch],
  );

  /** Convert an OwnerSearchResult → ParcelDetail so it can be added to the list */
  const ownerResultToParcelDetail = useCallback(
    (r: OwnerSearchResult): ParcelDetail => ({
      nrCad: r.nrCad,
      nrCF: r.nrCF,
      nrCFVechi: "",
      nrTopo: "",
      intravilan: r.intravilan,
      categorieFolosinta: r.categorieFolosinta,
      adresa: r.adresa,
      proprietari: r.proprietari || r.proprietariVechi,
      proprietariActuali: r.proprietari,
      proprietariVechi: r.proprietariVechi,
      suprafata: typeof r.suprafata === "number" ? r.suprafata : null,
      solicitant: "",
      immovablePk: r.immovablePk,
    }),
    [],
  );

  // Add result(s) to list for CSV export
  const addToList = useCallback((item: ParcelDetail) => {
    setSearchList((prev) => {
      if (
        prev.some(
          (p) => p.nrCad === item.nrCad && p.immovablePk === item.immovablePk,
        )
      )
        return prev;
      return [...prev, item];
    });
  }, []);

  const removeFromList = useCallback((nrCad: string) => {
    setSearchList((prev) => prev.filter((p) => p.nrCad !== nrCad));
  }, []);

  // CSV export — all fields quoted to handle commas in values (e.g. nrTopo)
  const csvEscape = useCallback((val: string | number | null | undefined) => {
    const s = val != null ? String(val) : "";
    return `"${s.replace(/"/g, '""')}"`;
  }, []);

  const downloadCSV = useCallback(() => {
    const items = searchList.length > 0 ? searchList : searchResults;
    if (items.length === 0) return;
    const headers = [
      "NR_CAD",
      "NR_CF",
      "NR_CF_VECHI",
      "NR_TOPO",
      "SUPRAFATA",
      "INTRAVILAN",
      "CATEGORIE_FOLOSINTA",
      "ADRESA",
      "PROPRIETARI_ACTUALI",
      "PROPRIETARI_VECHI",
      "SOLICITANT",
    ];
    const rows = items.map((p) => [
      csvEscape(p.nrCad),
      csvEscape(p.nrCF),
      csvEscape(p.nrCFVechi),
      csvEscape(p.nrTopo),
      csvEscape(p.suprafata),
      csvEscape(p.intravilan),
      csvEscape(p.categorieFolosinta),
      csvEscape(p.adresa),
      csvEscape(p.proprietariActuali ?? p.proprietari),
      csvEscape(p.proprietariVechi),
      csvEscape(p.solicitant),
    ]);
    const csv = [headers.join(","), ...rows.map((r) => r.join(","))].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 = `parcele_${siruta}_${Date.now()}.csv`;
    a.click();
    URL.revokeObjectURL(url);
  }, [searchList, searchResults, siruta, csvEscape]);

  /* ════════════════════════════════════════════════════════════ */
  /*  Derived data                                                 */
  /* ════════════════════════════════════════════════════════════ */

  const layersByCategory = useMemo(() => {
    const grouped: Record<string, LayerCatalogItem[]> = {};
    for (const layer of LAYER_CATALOG) {
      if (!grouped[layer.category]) grouped[layer.category] = [];
      grouped[layer.category]!.push(layer);
    }
    return grouped;
  }, []);

  const sirutaValid = siruta.length > 0 && /^\d+$/.test(siruta);

  const progressPct =
    exportProgress?.total && exportProgress.total > 0
      ? Math.round((exportProgress.downloaded / exportProgress.total) * 100)
      : 0;

  // DB status: which layers have data for the current UAT
  const dbLayersSummary = useMemo(() => {
    if (!sirutaValid || syncingSiruta !== siruta) return [];
    return LAYER_CATALOG.filter((l) => (syncLocalCounts[l.id] ?? 0) > 0).map(
      (l) => {
        const count = syncLocalCounts[l.id] ?? 0;
        const lastRun = syncRuns.find(
          (r) => r.layerId === l.id && r.status === "done",
        );
        const lastSynced = lastRun?.completedAt
          ? new Date(lastRun.completedAt)
          : null;
        const ageMs = lastSynced ? Date.now() - lastSynced.getTime() : null;
        const isFresh = ageMs !== null ? ageMs < 168 * 60 * 60 * 1000 : false;
        return { ...l, count, lastSynced, isFresh };
      },
    );
  }, [sirutaValid, syncingSiruta, siruta, syncLocalCounts, syncRuns]);

  const dbTotalFeatures = dbLayersSummary.reduce((sum, l) => sum + l.count, 0);

  const relativeTime = (date: Date | null) => {
    if (!date) return "niciodată";
    const mins = Math.floor((Date.now() - date.getTime()) / 60_000);
    if (mins < 1) return "acum";
    if (mins < 60) return `acum ${mins} min`;
    const hours = Math.floor(mins / 60);
    if (hours < 24) return `acum ${hours}h`;
    const days = Math.floor(hours / 24);
    return `acum ${days}z`;
  };

  /* ════════════════════════════════════════════════════════════ */
  /*  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 — always visible */}
          <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);
                  // Auto-connect on first keystroke
                  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>

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

            {/* Dropdown */}
            {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);
                      setSearchResults([]);
                    }}
                  >
                    <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 pill */}
          <ConnectionPill
            session={session}
            connecting={connecting}
            connectionError={connectionError}
            onDisconnect={handleDisconnect}
          />
        </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>
        </TabsList>
      </div>

      {/* ═══════════════════════════════════════════════════════ */}
      {/*  Tab 1: Parcel search                                    */}
      {/* ═══════════════════════════════════════════════════════ */}
      <TabsContent value="search" className="space-y-4">
        {!sirutaValid ? (
          <Card>
            <CardContent className="py-12 text-center text-muted-foreground">
              <Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
              <p>Selectează un UAT mai sus pentru a căuta parcele.</p>
            </CardContent>
          </Card>
        ) : (
          <>
            {/* Search input — mode toggle + input */}
            <Card>
              <CardContent className="pt-4 space-y-3">
                {/* Mode toggle */}
                <div className="flex gap-1 p-0.5 bg-muted rounded-md w-fit">
                  <button
                    onClick={() => setSearchMode("cadastral")}
                    className={cn(
                      "px-3 py-1 text-xs rounded font-medium transition-colors",
                      searchMode === "cadastral"
                        ? "bg-background shadow text-foreground"
                        : "text-muted-foreground hover:text-foreground",
                    )}
                  >
                    <Search className="inline h-3 w-3 mr-1 -mt-0.5" />
                    Nr. Cadastral
                  </button>
                  <button
                    onClick={() => setSearchMode("owner")}
                    className={cn(
                      "px-3 py-1 text-xs rounded font-medium transition-colors",
                      searchMode === "owner"
                        ? "bg-background shadow text-foreground"
                        : "text-muted-foreground hover:text-foreground",
                    )}
                  >
                    <User className="inline h-3 w-3 mr-1 -mt-0.5" />
                    Proprietar
                  </button>
                </div>

                {/* Cadastral search input */}
                {searchMode === "cadastral" && (
                  <div className="flex gap-3 items-end">
                    <div className="space-y-1 flex-1">
                      <Label className="text-xs">
                        Numere cadastrale (separate prin virgulă sau Enter)
                      </Label>
                      <div className="relative">
                        <Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
                        <Input
                          placeholder="ex: 62580 sau 62580, 62581, 62582"
                          className="pl-9"
                          value={featuresSearch}
                          onChange={(e) => setFeaturesSearch(e.target.value)}
                          onKeyDown={handleSearchKeyDown}
                          disabled={!session.connected}
                        />
                      </div>
                      {!session.connected && (
                        <p className="text-xs text-muted-foreground">
                          Necesită conexiune eTerra. Folosește modul Proprietar
                          pentru a căuta offline în DB.
                        </p>
                      )}
                    </div>
                    <Button
                      onClick={() => void handleSearch()}
                      disabled={
                        loadingFeatures ||
                        !featuresSearch.trim() ||
                        !session.connected
                      }
                    >
                      {loadingFeatures ? (
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      ) : (
                        <Search className="mr-2 h-4 w-4" />
                      )}
                      Caută
                    </Button>
                  </div>
                )}

                {/* Owner search input */}
                {searchMode === "owner" && (
                  <div className="flex gap-3 items-end">
                    <div className="space-y-1 flex-1">
                      <Label className="text-xs">
                        Nume proprietar (caută în DB local + eTerra)
                      </Label>
                      <div className="relative">
                        <User className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
                        <Input
                          placeholder="ex: Popescu Ion"
                          className="pl-9"
                          value={ownerSearch}
                          onChange={(e) => setOwnerSearch(e.target.value)}
                          onKeyDown={handleOwnerKeyDown}
                        />
                      </div>
                    </div>
                    <Button
                      onClick={() => void handleOwnerSearch()}
                      disabled={ownerLoading || ownerSearch.trim().length < 2}
                    >
                      {ownerLoading ? (
                        <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                      ) : (
                        <Search className="mr-2 h-4 w-4" />
                      )}
                      Caută
                    </Button>
                  </div>
                )}

                {searchMode === "cadastral" && searchError && (
                  <p className="text-xs text-destructive">{searchError}</p>
                )}
                {searchMode === "owner" && ownerError && (
                  <p className="text-xs text-destructive">{ownerError}</p>
                )}
                {searchMode === "owner" && ownerNote && (
                  <p className="text-xs text-muted-foreground">{ownerNote}</p>
                )}
              </CardContent>
            </Card>

            {/* ─── Cadastral search results ────────────── */}
            {searchMode === "cadastral" && (
              <>
                {/* Results */}
                {loadingFeatures && searchResults.length === 0 && (
                  <Card>
                    <CardContent className="py-12 text-center text-muted-foreground">
                      <Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
                      <p>Se caută în eTerra...</p>
                      <p className="text-xs mt-1 opacity-60">
                        Prima căutare pe un UAT nou poate dura ~10-30s (se
                        încarcă lista de județe).
                      </p>
                    </CardContent>
                  </Card>
                )}

                {searchResults.length > 0 && (
                  <>
                    {/* Action bar */}
                    <div className="flex items-center justify-between">
                      <span className="text-sm text-muted-foreground">
                        {searchResults.length} rezultat
                        {searchResults.length > 1 ? "e" : ""}
                        {searchList.length > 0 && (
                          <span className="ml-2">
                            · <strong>{searchList.length}</strong> în listă
                          </span>
                        )}
                      </span>
                      <div className="flex gap-2">
                        {searchResults.length > 0 && (
                          <Button
                            size="sm"
                            variant="outline"
                            onClick={() => {
                              for (const r of searchResults) addToList(r);
                            }}
                          >
                            <Plus className="mr-1 h-3.5 w-3.5" />
                            Adaugă toate în listă
                          </Button>
                        )}
                        <Button
                          size="sm"
                          variant="default"
                          onClick={downloadCSV}
                          disabled={
                            searchResults.length === 0 &&
                            searchList.length === 0
                          }
                        >
                          <FileDown className="mr-1 h-3.5 w-3.5" />
                          Descarcă CSV
                        </Button>
                      </div>
                    </div>

                    {/* Detail cards */}
                    <div className="space-y-3">
                      {searchResults.map((p, idx) => (
                        <Card
                          key={`${p.nrCad}-${p.immovablePk}-${idx}`}
                          className={cn(
                            "transition-colors",
                            !p.immovablePk && "opacity-60",
                          )}
                        >
                          <CardContent className="pt-4">
                            <div className="flex items-start justify-between mb-3">
                              <div>
                                <h3 className="text-lg font-semibold tabular-nums">
                                  Nr. Cad. {p.nrCad}
                                </h3>
                                {!p.immovablePk && (
                                  <p className="text-xs text-destructive">
                                    Parcela nu a fost găsită în eTerra.
                                  </p>
                                )}
                              </div>
                              <div className="flex gap-1">
                                <Button
                                  size="sm"
                                  variant="ghost"
                                  className="h-7 w-7 p-0"
                                  title="Adaugă în listă"
                                  onClick={() => addToList(p)}
                                  disabled={!p.immovablePk}
                                >
                                  <Plus className="h-3.5 w-3.5" />
                                </Button>
                                <Button
                                  size="sm"
                                  variant="ghost"
                                  className="h-7 w-7 p-0"
                                  title="Copiază detalii"
                                  onClick={() => {
                                    const text = [
                                      `Nr. Cad: ${p.nrCad}`,
                                      `Nr. CF: ${p.nrCF || "—"}`,
                                      p.nrCFVechi
                                        ? `CF vechi: ${p.nrCFVechi}`
                                        : null,
                                      p.nrTopo ? `Nr. Topo: ${p.nrTopo}` : null,
                                      p.suprafata != null
                                        ? `Suprafață: ${p.suprafata.toLocaleString("ro-RO")} mp`
                                        : null,
                                      `Intravilan: ${p.intravilan || "—"}`,
                                      p.categorieFolosinta
                                        ? `Categorie: ${p.categorieFolosinta}`
                                        : null,
                                      p.adresa ? `Adresă: ${p.adresa}` : null,
                                      p.proprietariActuali
                                        ? `Proprietari actuali: ${p.proprietariActuali}`
                                        : null,
                                      p.proprietariVechi
                                        ? `Proprietari vechi: ${p.proprietariVechi}`
                                        : null,
                                      !p.proprietariActuali &&
                                      !p.proprietariVechi &&
                                      p.proprietari
                                        ? `Proprietari: ${p.proprietari}`
                                        : null,
                                      p.solicitant
                                        ? `Solicitant: ${p.solicitant}`
                                        : null,
                                    ]
                                      .filter(Boolean)
                                      .join("\n");
                                    void navigator.clipboard.writeText(text);
                                  }}
                                >
                                  <ClipboardCopy className="h-3.5 w-3.5" />
                                </Button>
                              </div>
                            </div>

                            {p.immovablePk && (
                              <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-x-6 gap-y-2 text-sm">
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Nr. CF
                                  </span>
                                  <span className="font-medium">
                                    {p.nrCF || "—"}
                                  </span>
                                </div>
                                {p.nrCFVechi && (
                                  <div>
                                    <span className="text-xs text-muted-foreground block">
                                      CF vechi
                                    </span>
                                    <span>{p.nrCFVechi}</span>
                                  </div>
                                )}
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Nr. Topo
                                  </span>
                                  <span>{p.nrTopo || "—"}</span>
                                </div>
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Suprafață
                                  </span>
                                  <span className="tabular-nums">
                                    {p.suprafata != null
                                      ? formatArea(p.suprafata)
                                      : "—"}
                                  </span>
                                </div>
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Intravilan
                                  </span>
                                  <Badge
                                    variant={
                                      p.intravilan === "Da"
                                        ? "default"
                                        : p.intravilan === "Nu"
                                          ? "secondary"
                                          : "outline"
                                    }
                                    className="text-[11px]"
                                  >
                                    {p.intravilan || "—"}
                                  </Badge>
                                </div>
                                {p.categorieFolosinta && (
                                  <div className="col-span-2">
                                    <span className="text-xs text-muted-foreground block">
                                      Categorii folosință
                                    </span>
                                    <span className="text-xs">
                                      {p.categorieFolosinta}
                                    </span>
                                  </div>
                                )}
                                {p.adresa && (
                                  <div className="col-span-2">
                                    <span className="text-xs text-muted-foreground block">
                                      Adresă
                                    </span>
                                    <span>{p.adresa}</span>
                                  </div>
                                )}
                                {(p.proprietariActuali ||
                                  p.proprietariVechi) && (
                                  <div className="col-span-2 lg:col-span-4">
                                    {p.proprietariActuali && (
                                      <div className="mb-1">
                                        <span className="text-xs text-muted-foreground block">
                                          Proprietari actuali
                                        </span>
                                        <span className="font-medium text-sm">
                                          {p.proprietariActuali}
                                        </span>
                                      </div>
                                    )}
                                    {p.proprietariVechi && (
                                      <div>
                                        <span className="text-xs text-muted-foreground block">
                                          Proprietari anteriori
                                        </span>
                                        <span className="text-[11px] text-muted-foreground/80">
                                          {p.proprietariVechi}
                                        </span>
                                      </div>
                                    )}
                                    {!p.proprietariActuali &&
                                      !p.proprietariVechi &&
                                      p.proprietari && (
                                        <div>
                                          <span className="text-xs text-muted-foreground block">
                                            Proprietari
                                          </span>
                                          <span>{p.proprietari}</span>
                                        </div>
                                      )}
                                  </div>
                                )}
                                {p.solicitant && (
                                  <div className="col-span-2">
                                    <span className="text-xs text-muted-foreground block">
                                      Solicitant
                                    </span>
                                    <span>{p.solicitant}</span>
                                  </div>
                                )}
                              </div>
                            )}
                          </CardContent>
                        </Card>
                      ))}
                    </div>
                  </>
                )}

                {/* Empty state when no search has been done */}
                {searchMode === "cadastral" &&
                  searchResults.length === 0 &&
                  !loadingFeatures &&
                  !searchError && (
                    <Card>
                      <CardContent className="py-12 text-center text-muted-foreground">
                        <Search className="h-10 w-10 mx-auto mb-3 opacity-30" />
                        <p>Introdu un număr cadastral și apasă Caută.</p>
                        <p className="text-xs mt-1 opacity-60">
                          Poți căuta mai multe parcele simultan, separate prin
                          virgulă.
                        </p>
                      </CardContent>
                    </Card>
                  )}
              </>
            )}

            {/* ─── Owner search results ────────────────── */}
            {searchMode === "owner" && (
              <>
                {ownerLoading && ownerResults.length === 0 && (
                  <Card>
                    <CardContent className="py-12 text-center text-muted-foreground">
                      <Loader2 className="h-10 w-10 mx-auto mb-3 animate-spin opacity-50" />
                      <p>Se caută proprietar...</p>
                      <p className="text-xs mt-1 opacity-60">
                        Caută mai întâi în DB local (date îmbogățite), apoi pe
                        eTerra.
                      </p>
                    </CardContent>
                  </Card>
                )}

                {ownerResults.length > 0 && (
                  <>
                    <div className="flex items-center justify-between">
                      <span className="text-sm text-muted-foreground">
                        {ownerResults.length} rezultat
                        {ownerResults.length > 1 ? "e" : ""} pentru &quot;
                        {ownerSearch}&quot;
                      </span>
                      <div className="flex gap-2">
                        <Button
                          size="sm"
                          variant="outline"
                          onClick={() => {
                            for (const r of ownerResults)
                              addToList(ownerResultToParcelDetail(r));
                          }}
                        >
                          <Plus className="mr-1 h-3.5 w-3.5" />
                          Adaugă toate în listă
                        </Button>
                        <Button
                          size="sm"
                          variant="default"
                          onClick={downloadCSV}
                          disabled={
                            ownerResults.length === 0 && searchList.length === 0
                          }
                        >
                          <FileDown className="mr-1 h-3.5 w-3.5" />
                          Descarcă CSV
                        </Button>
                      </div>
                    </div>

                    <div className="space-y-3">
                      {ownerResults.map((r, idx) => (
                        <Card key={`owner-${r.nrCad}-${idx}`}>
                          <CardContent className="pt-4">
                            <div className="flex items-start justify-between mb-3">
                              <div>
                                <h3 className="text-lg font-semibold tabular-nums">
                                  Nr. Cad. {r.nrCad}
                                </h3>
                                <Badge
                                  variant="outline"
                                  className="text-[10px] mt-1"
                                >
                                  {r.source === "db"
                                    ? "din baza de date"
                                    : "eTerra online"}
                                </Badge>
                              </div>
                              <div className="flex gap-1">
                                <Button
                                  size="sm"
                                  variant="ghost"
                                  className="h-7 w-7 p-0"
                                  title="Adaugă în listă"
                                  onClick={() =>
                                    addToList(ownerResultToParcelDetail(r))
                                  }
                                >
                                  <Plus className="h-3.5 w-3.5" />
                                </Button>
                                <Button
                                  size="sm"
                                  variant="ghost"
                                  className="h-7 w-7 p-0"
                                  title="Copiază detalii"
                                  onClick={() => {
                                    const text = [
                                      `Nr. Cad: ${r.nrCad}`,
                                      r.nrCF ? `Nr. CF: ${r.nrCF}` : null,
                                      r.proprietari
                                        ? `Proprietari: ${r.proprietari}`
                                        : null,
                                      r.proprietariVechi
                                        ? `Proprietari vechi: ${r.proprietariVechi}`
                                        : null,
                                      r.adresa ? `Adresă: ${r.adresa}` : null,
                                      r.suprafata
                                        ? `Suprafață: ${r.suprafata} mp`
                                        : null,
                                    ]
                                      .filter(Boolean)
                                      .join("\n");
                                    void navigator.clipboard.writeText(text);
                                  }}
                                >
                                  <ClipboardCopy className="h-3.5 w-3.5" />
                                </Button>
                              </div>
                            </div>

                            <div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-x-6 gap-y-2 text-sm">
                              {r.nrCF && (
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Nr. CF
                                  </span>
                                  <span className="font-medium">{r.nrCF}</span>
                                </div>
                              )}
                              {r.suprafata && (
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Suprafață
                                  </span>
                                  <span className="tabular-nums">
                                    {typeof r.suprafata === "number"
                                      ? formatArea(r.suprafata)
                                      : `${r.suprafata} mp`}
                                  </span>
                                </div>
                              )}
                              {r.intravilan && (
                                <div>
                                  <span className="text-xs text-muted-foreground block">
                                    Intravilan
                                  </span>
                                  <Badge
                                    variant={
                                      r.intravilan === "Da"
                                        ? "default"
                                        : r.intravilan === "Nu"
                                          ? "secondary"
                                          : "outline"
                                    }
                                    className="text-[11px]"
                                  >
                                    {r.intravilan}
                                  </Badge>
                                </div>
                              )}
                              {r.categorieFolosinta && (
                                <div className="col-span-2">
                                  <span className="text-xs text-muted-foreground block">
                                    Categorii folosință
                                  </span>
                                  <span className="text-xs">
                                    {r.categorieFolosinta}
                                  </span>
                                </div>
                              )}
                              {r.adresa && (
                                <div className="col-span-2">
                                  <span className="text-xs text-muted-foreground block">
                                    Adresă
                                  </span>
                                  <span>{r.adresa}</span>
                                </div>
                              )}
                              {r.proprietari && (
                                <div className="col-span-2 lg:col-span-4">
                                  <span className="text-xs text-muted-foreground block">
                                    Proprietari actuali
                                  </span>
                                  <span className="font-medium text-sm">
                                    {r.proprietari}
                                  </span>
                                </div>
                              )}
                              {r.proprietariVechi && (
                                <div className="col-span-2 lg:col-span-4">
                                  <span className="text-xs text-muted-foreground block">
                                    Proprietari anteriori
                                  </span>
                                  <span className="text-[11px] text-muted-foreground/80">
                                    {r.proprietariVechi}
                                  </span>
                                </div>
                              )}
                            </div>
                          </CardContent>
                        </Card>
                      ))}
                    </div>
                  </>
                )}

                {ownerResults.length === 0 && !ownerLoading && !ownerError && (
                  <Card>
                    <CardContent className="py-12 text-center text-muted-foreground">
                      <User className="h-10 w-10 mx-auto mb-3 opacity-30" />
                      <p>Introdu numele proprietarului și apasă Caută.</p>
                      <p className="text-xs mt-1 opacity-60">
                        Caută în datele îmbogățite (DB local) și pe eTerra.
                        <br />
                        Pentru rezultate complete, lansează &quot;Sync fundal —
                        Magic&quot; în tab-ul Export.
                      </p>
                    </CardContent>
                  </Card>
                )}
              </>
            )}

            {/* Saved list */}
            {searchList.length > 0 && (
              <Card>
                <CardContent className="pt-4">
                  <div className="flex items-center justify-between mb-3">
                    <h3 className="text-sm font-medium">
                      Lista mea ({searchList.length} parcele)
                    </h3>
                    <div className="flex gap-2">
                      <Button
                        size="sm"
                        variant="outline"
                        onClick={() => setSearchList([])}
                      >
                        <Trash2 className="mr-1 h-3.5 w-3.5" />
                        Golește
                      </Button>
                      <Button size="sm" onClick={downloadCSV}>
                        <FileDown className="mr-1 h-3.5 w-3.5" />
                        CSV din listă
                      </Button>
                    </div>
                  </div>
                  <div className="overflow-x-auto">
                    <table className="w-full text-sm">
                      <thead>
                        <tr className="border-b bg-muted/40">
                          <th className="px-3 py-2 text-left font-medium">
                            Nr. Cad
                          </th>
                          <th className="px-3 py-2 text-left font-medium">
                            Nr. CF
                          </th>
                          <th className="px-3 py-2 text-right font-medium hidden sm:table-cell">
                            Suprafață
                          </th>
                          <th className="px-3 py-2 text-left font-medium hidden md:table-cell">
                            Proprietari
                          </th>
                          <th className="px-3 py-2 w-8"></th>
                        </tr>
                      </thead>
                      <tbody>
                        {searchList.map((p) => (
                          <tr
                            key={`list-${p.nrCad}-${p.immovablePk}`}
                            className="border-b hover:bg-muted/30 transition-colors"
                          >
                            <td className="px-3 py-2 font-mono text-xs font-medium">
                              {p.nrCad}
                            </td>
                            <td className="px-3 py-2 text-xs">
                              {p.nrCF || "—"}
                            </td>
                            <td className="px-3 py-2 text-right hidden sm:table-cell tabular-nums text-xs">
                              {p.suprafata != null
                                ? formatArea(p.suprafata)
                                : "—"}
                            </td>
                            <td className="px-3 py-2 hidden md:table-cell text-xs truncate max-w-[300px]">
                              {p.proprietari || "—"}
                            </td>
                            <td className="px-3 py-2">
                              <Button
                                size="sm"
                                variant="ghost"
                                className="h-6 w-6 p-0"
                                onClick={() => removeFromList(p.nrCad)}
                              >
                                <XCircle className="h-3.5 w-3.5" />
                              </Button>
                            </td>
                          </tr>
                        ))}
                      </tbody>
                    </table>
                  </div>
                </CardContent>
              </Card>
            )}
          </>
        )}
      </TabsContent>

      {/* ═══════════════════════════════════════════════════════ */}
      {/*  Tab 2: Layer catalog                                    */}
      {/* ═══════════════════════════════════════════════════════ */}
      <TabsContent value="layers" className="space-y-4">
        {!sirutaValid || !session.connected ? (
          <Card>
            <CardContent className="py-12 text-center text-muted-foreground">
              <Layers className="h-10 w-10 mx-auto mb-3 opacity-30" />
              <p>
                {!session.connected
                  ? "Conectează-te la eTerra și selectează un UAT."
                  : "Selectează un UAT pentru a vedea catalogul de layere."}
              </p>
            </CardContent>
          </Card>
        ) : (
          <div className="space-y-3">
            {/* Action bar */}
            <div className="flex items-center justify-between gap-2 flex-wrap">
              <p className="text-xs text-muted-foreground">
                {layerCountSiruta === siruta &&
                Object.keys(layerCounts).length > 0
                  ? `Număr features pentru SIRUTA ${siruta}`
                  : "Apasă pentru a număra features-urile din fiecare layer."}
              </p>
              <div className="flex items-center gap-2">
                {/* Export from local DB */}
                {syncingSiruta === siruta &&
                  Object.values(syncLocalCounts).some((c) => c > 0) && (
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={exportingLocal}
                      onClick={() => void handleExportLocal()}
                      className="border-violet-300 text-violet-700 dark:border-violet-700 dark:text-violet-300"
                    >
                      {exportingLocal ? (
                        <Loader2 className="h-3.5 w-3.5 animate-spin mr-1.5" />
                      ) : (
                        <HardDrive className="h-3.5 w-3.5 mr-1.5" />
                      )}
                      Export local
                    </Button>
                  )}
                <Button
                  size="sm"
                  variant="outline"
                  disabled={countingLayers}
                  onClick={() => void fetchLayerCounts()}
                >
                  {countingLayers ? (
                    <Loader2 className="h-3.5 w-3.5 animate-spin mr-1.5" />
                  ) : (
                    <Search className="h-3.5 w-3.5 mr-1.5" />
                  )}
                  {countingLayers ? "Se numără…" : "Numără"}
                </Button>
              </div>
            </div>

            {/* Sync progress message */}
            {syncProgress && (
              <div className="flex items-center gap-2 rounded-lg border px-3 py-2 text-xs">
                {syncingLayer ? (
                  <Loader2 className="h-3.5 w-3.5 animate-spin text-blue-500 shrink-0" />
                ) : (
                  <CheckCircle2 className="h-3.5 w-3.5 text-emerald-500 shrink-0" />
                )}
                <span>{syncProgress}</span>
              </div>
            )}

            {(Object.keys(LAYER_CATEGORY_LABELS) as LayerCategory[]).map(
              (cat) => {
                const layers = layersByCategory[cat];
                if (!layers?.length) return null;
                const isExpanded = expandedCategories[cat] ?? false;

                // Sum counts for category badge
                const catTotal =
                  layerCountSiruta === siruta
                    ? layers.reduce(
                        (sum, l) => sum + (layerCounts[l.id]?.count ?? 0),
                        0,
                      )
                    : null;

                // Sum local counts for category
                const catLocal =
                  syncingSiruta === siruta
                    ? layers.reduce(
                        (sum, l) => sum + (syncLocalCounts[l.id] ?? 0),
                        0,
                      )
                    : null;

                return (
                  <Card key={cat}>
                    <button
                      type="button"
                      className="w-full flex items-center justify-between px-4 py-3 text-left hover:bg-muted/50 transition-colors rounded-t-xl"
                      onClick={() =>
                        setExpandedCategories((prev) => ({
                          ...prev,
                          [cat]: !prev[cat],
                        }))
                      }
                    >
                      <div className="flex items-center gap-2 flex-wrap">
                        <span className="text-sm font-semibold">
                          {LAYER_CATEGORY_LABELS[cat]}
                        </span>
                        <Badge
                          variant="outline"
                          className="font-normal text-[11px]"
                        >
                          {layers.length}
                        </Badge>
                        {catTotal != null && catTotal > 0 && (
                          <Badge className="font-mono text-[10px] bg-blue-100 text-blue-700 dark:bg-blue-900/40 dark:text-blue-300 border-0">
                            {catTotal.toLocaleString("ro-RO")} remote
                          </Badge>
                        )}
                        {catLocal != null && catLocal > 0 && (
                          <Badge className="font-mono text-[10px] bg-violet-100 text-violet-700 dark:bg-violet-900/40 dark:text-violet-300 border-0">
                            {catLocal.toLocaleString("ro-RO")} local
                          </Badge>
                        )}
                      </div>
                      {isExpanded ? (
                        <ChevronUp className="h-4 w-4 text-muted-foreground" />
                      ) : (
                        <ChevronDown className="h-4 w-4 text-muted-foreground" />
                      )}
                    </button>

                    {isExpanded && (
                      <CardContent className="pt-0 pb-3 space-y-1.5">
                        {layers.map((layer) => {
                          const isDownloading = downloadingLayer === layer.id;
                          const isSyncing = syncingLayer === layer.id;
                          const lc =
                            layerCountSiruta === siruta
                              ? layerCounts[layer.id]
                              : undefined;
                          const localCount =
                            syncingSiruta === siruta
                              ? (syncLocalCounts[layer.id] ?? 0)
                              : 0;

                          // Find last sync run for this layer
                          const lastRun = syncRuns.find(
                            (r) =>
                              r.layerId === layer.id && r.status === "done",
                          );

                          return (
                            <div
                              key={layer.id}
                              className={cn(
                                "rounded-lg border px-3 py-2.5 transition-colors",
                                isDownloading || isSyncing
                                  ? "border-blue-300 bg-blue-50/50 dark:border-blue-700 dark:bg-blue-950/20"
                                  : "hover:bg-muted/50",
                              )}
                            >
                              <div className="flex items-center justify-between gap-3">
                                <div className="min-w-0 flex-1">
                                  <div className="flex items-center gap-2 flex-wrap">
                                    <p className="text-sm font-medium truncate">
                                      {layer.label}
                                    </p>
                                    {lc != null && !lc.error && (
                                      <Badge
                                        variant="secondary"
                                        className={cn(
                                          "font-mono text-[10px] shrink-0",
                                          lc.count === 0
                                            ? "opacity-40"
                                            : "bg-emerald-100 text-emerald-700 dark:bg-emerald-900/40 dark:text-emerald-300",
                                        )}
                                      >
                                        {lc.count.toLocaleString("ro-RO")}
                                      </Badge>
                                    )}
                                    {lc?.error && (
                                      <span className="text-[10px] text-rose-500">
                                        eroare
                                      </span>
                                    )}
                                    {localCount > 0 && (
                                      <Badge className="font-mono text-[10px] bg-violet-100 text-violet-700 dark:bg-violet-900/40 dark:text-violet-300 border-0 shrink-0">
                                        <Database className="h-2.5 w-2.5 mr-0.5" />
                                        {localCount.toLocaleString("ro-RO")}
                                      </Badge>
                                    )}
                                  </div>
                                  <div className="flex items-center gap-2">
                                    <p className="text-[11px] text-muted-foreground font-mono">
                                      {layer.id}
                                    </p>
                                    {lastRun && (
                                      <span className="text-[10px] text-muted-foreground/70">
                                        sync{" "}
                                        {new Date(
                                          lastRun.completedAt ??
                                            lastRun.startedAt,
                                        ).toLocaleDateString("ro-RO", {
                                          day: "2-digit",
                                          month: "2-digit",
                                          hour: "2-digit",
                                          minute: "2-digit",
                                        })}
                                      </span>
                                    )}
                                  </div>
                                </div>
                                <div className="flex items-center gap-1.5 shrink-0">
                                  {/* Sync to DB */}
                                  <Button
                                    size="sm"
                                    variant="outline"
                                    disabled={
                                      !!syncingLayer ||
                                      !!downloadingLayer ||
                                      exporting
                                    }
                                    onClick={() =>
                                      void handleSyncLayer(layer.id)
                                    }
                                    className="border-violet-200 dark:border-violet-800"
                                    title="Sincronizează în baza de date"
                                  >
                                    {isSyncing ? (
                                      <Loader2 className="h-3.5 w-3.5 animate-spin" />
                                    ) : (
                                      <RefreshCw className="h-3.5 w-3.5" />
                                    )}
                                    <span className="ml-1.5 hidden sm:inline">
                                      Sync
                                    </span>
                                  </Button>
                                  {/* GPKG (sync-first: syncs to DB if needed, then exports from DB) */}
                                  <Button
                                    size="sm"
                                    variant="outline"
                                    disabled={!!downloadingLayer || exporting}
                                    onClick={() =>
                                      void handleExportLayer(layer.id)
                                    }
                                    title={
                                      localCount > 0
                                        ? "Descarcă GPKG (din cache dacă e proaspăt)"
                                        : "Sincronizează + descarcă GPKG"
                                    }
                                  >
                                    {isDownloading ? (
                                      <Loader2 className="h-3.5 w-3.5 animate-spin" />
                                    ) : (
                                      <Download className="h-3.5 w-3.5" />
                                    )}
                                    <span className="ml-1.5 hidden sm:inline">
                                      GPKG
                                    </span>
                                  </Button>
                                </div>
                              </div>
                            </div>
                          );
                        })}
                      </CardContent>
                    )}
                  </Card>
                );
              },
            )}

            {/* Drumul de azi — today's layer count history */}
            {layerHistory.length > 0 && (
              <Card>
                <div className="px-4 py-3 border-b">
                  <div className="flex items-center gap-2">
                    <Sparkles className="h-4 w-4 text-amber-500" />
                    <span className="text-sm font-semibold">Drumul de azi</span>
                    <Badge
                      variant="outline"
                      className="font-normal text-[11px]"
                    >
                      {layerHistory.length}
                    </Badge>
                  </div>
                </div>
                <CardContent className="pt-3 pb-3">
                  <div className="space-y-2 max-h-64 overflow-y-auto">
                    {/* Group by siruta */}
                    {(() => {
                      const grouped = new Map<string, typeof layerHistory>();
                      for (const e of layerHistory) {
                        if (!grouped.has(e.siruta)) grouped.set(e.siruta, []);
                        grouped.get(e.siruta)!.push(e);
                      }
                      return Array.from(grouped.entries()).map(
                        ([sir, entries]) => (
                          <div key={sir} className="space-y-1">
                            <p className="text-[11px] font-semibold text-muted-foreground">
                              SIRUTA {sir}{" "}
                              <span className="font-normal opacity-70">
                                —{" "}
                                {new Date(entries[0]!.time).toLocaleTimeString(
                                  "ro-RO",
                                  { hour: "2-digit", minute: "2-digit" },
                                )}
                              </span>
                            </p>
                            <div className="grid grid-cols-2 sm:grid-cols-3 gap-1">
                              {entries
                                .sort((a, b) => b.count - a.count)
                                .map((e) => (
                                  <div
                                    key={e.layerId}
                                    className="flex items-center justify-between gap-1 rounded border px-2 py-1 text-[11px]"
                                  >
                                    <span className="truncate">{e.label}</span>
                                    <span className="font-mono font-semibold text-emerald-600 dark:text-emerald-400 shrink-0">
                                      {e.count.toLocaleString("ro-RO")}
                                    </span>
                                  </div>
                                ))}
                            </div>
                          </div>
                        ),
                      );
                    })()}
                  </div>
                </CardContent>
              </Card>
            )}

            {/* PostGIS / QGIS setup */}
            <Card>
              <div className="px-4 py-3 border-b">
                <div className="flex items-center justify-between">
                  <div className="flex items-center gap-2">
                    <Database className="h-4 w-4 text-violet-500" />
                    <span className="text-sm font-semibold">
                      QGIS / PostGIS
                    </span>
                  </div>
                  <Button
                    size="sm"
                    variant="outline"
                    disabled={postgisRunning}
                    onClick={() => void handleSetupPostgis()}
                    className="border-violet-300 text-violet-700 dark:border-violet-700 dark:text-violet-300"
                  >
                    {postgisRunning ? (
                      <Loader2 className="h-3.5 w-3.5 animate-spin mr-1.5" />
                    ) : (
                      <Database className="h-3.5 w-3.5 mr-1.5" />
                    )}
                    {postgisRunning ? "Se configurează…" : "Setup PostGIS"}
                  </Button>
                </div>
              </div>
              <CardContent className="py-3 space-y-2">
                {postgisResult ? (
                  postgisResult.success ? (
                    <div className="space-y-2">
                      <div className="flex items-center gap-2">
                        <CheckCircle2 className="h-4 w-4 text-emerald-500" />
                        <span className="text-sm font-medium text-emerald-700 dark:text-emerald-400">
                          {postgisResult.message}
                        </span>
                      </div>
                      {postgisResult.details && (
                        <div className="rounded bg-muted/50 p-3 text-xs space-y-1 font-mono">
                          <p>
                            Backfill:{" "}
                            {String(
                              (
                                postgisResult.details as {
                                  backfilledFeatures?: number;
                                }
                              ).backfilledFeatures ?? 0,
                            )}{" "}
                            features convertite
                          </p>
                          <p>
                            Total cu geometrie nativă:{" "}
                            {String(
                              (
                                postgisResult.details as {
                                  totalFeaturesWithGeom?: number;
                                }
                              ).totalFeaturesWithGeom ?? 0,
                            )}
                          </p>
                          <p className="text-muted-foreground mt-1">
                            QGIS → PostgreSQL → 10.10.10.166:5432 /
                            architools_db
                          </p>
                          <p className="text-muted-foreground">
                            View-uri: gis_terenuri, gis_cladiri,
                            gis_documentatii, gis_administrativ
                          </p>
                          <p className="text-muted-foreground">SRID: 3844</p>
                        </div>
                      )}
                    </div>
                  ) : (
                    <div className="flex items-start gap-2">
                      <XCircle className="h-4 w-4 text-red-500 shrink-0 mt-0.5" />
                      <div className="text-sm">
                        <p className="font-medium text-red-700 dark:text-red-400">
                          PostGIS nu este instalat
                        </p>
                        <p className="text-xs text-muted-foreground mt-1">
                          Instalează PostGIS pe serverul PostgreSQL:
                        </p>
                        <code className="text-xs block mt-1 bg-muted rounded px-2 py-1">
                          apt install postgresql-16-postgis-3
                        </code>
                      </div>
                    </div>
                  )
                ) : (
                  <p className="text-xs text-muted-foreground">
                    Creează coloana nativă PostGIS, trigger auto-conversie,
                    index spațial GiST și view-uri QGIS-compatibile. Necesită
                    PostGIS instalat pe server.
                  </p>
                )}
              </CardContent>
            </Card>
          </div>
        )}

        {/* Progress bar for layer download */}
        {downloadingLayer && exportProgress && (
          <Card className="border-blue-200 dark:border-blue-800">
            <CardContent className="pt-4 space-y-2">
              <div className="flex items-center gap-3">
                <Loader2 className="h-5 w-5 text-blue-600 animate-spin shrink-0" />
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-medium">
                    {exportProgress.phase}
                    {exportProgress.phaseCurrent != null &&
                    exportProgress.phaseTotal
                      ? ` — ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
                      : ""}
                  </p>
                </div>
                <span className="text-sm font-mono font-semibold tabular-nums">
                  {progressPct}%
                </span>
              </div>
              <div className="h-2 w-full rounded-full bg-blue-200/50 dark:bg-blue-800/30">
                <div
                  className="h-2 rounded-full bg-blue-600 transition-all duration-300"
                  style={{ width: `${Math.max(2, progressPct)}%` }}
                />
              </div>
            </CardContent>
          </Card>
        )}
      </TabsContent>

      {/* ═══════════════════════════════════════════════════════ */}
      {/*  Tab 3: Export                                           */}
      {/* ═══════════════════════════════════════════════════════ */}
      <TabsContent value="export" className="space-y-4">
        {/* DB freshness status */}
        {sirutaValid && dbLayersSummary.length > 0 && (
          <Card className="border-dashed">
            <CardContent className="py-3 px-4">
              <div className="flex items-center gap-3 flex-wrap">
                <Database className="h-4 w-4 text-muted-foreground shrink-0" />
                <span className="text-sm text-muted-foreground">
                  <span className="font-medium text-foreground">
                    {dbTotalFeatures.toLocaleString("ro-RO")}
                  </span>{" "}
                  entități în DB din{" "}
                  <span className="font-medium text-foreground">
                    {dbLayersSummary.length}
                  </span>{" "}
                  layere
                </span>
                {(() => {
                  const freshCount = dbLayersSummary.filter(
                    (l) => l.isFresh,
                  ).length;
                  const staleCount = dbLayersSummary.length - freshCount;
                  const oldestSync = dbLayersSummary.reduce(
                    (oldest, l) => {
                      if (!l.lastSynced) return oldest;
                      if (!oldest || l.lastSynced < oldest) return l.lastSynced;
                      return oldest;
                    },
                    null as Date | null,
                  );
                  return (
                    <>
                      {staleCount === 0 ? (
                        <Badge
                          variant="outline"
                          className="text-emerald-600 border-emerald-200 dark:text-emerald-400 dark:border-emerald-800"
                        >
                          <CheckCircle2 className="h-3 w-3 mr-1" />
                          Proaspete
                        </Badge>
                      ) : (
                        <Badge
                          variant="outline"
                          className="text-amber-600 border-amber-200 dark:text-amber-400 dark:border-amber-800"
                        >
                          <Clock className="h-3 w-3 mr-1" />
                          {staleCount} vechi
                        </Badge>
                      )}
                      {oldestSync && (
                        <span className="text-xs text-muted-foreground">
                          Ultima sincronizare: {relativeTime(oldestSync)}
                        </span>
                      )}
                    </>
                  );
                })()}
              </div>
            </CardContent>
          </Card>
        )}

        {/* Hero buttons */}
        {sirutaValid && session.connected ? (
          <div className="grid gap-3 sm:grid-cols-2">
            <Button
              size="lg"
              className="h-auto py-4 text-base bg-zinc-900 hover:bg-zinc-800 text-white dark:bg-zinc-100 dark:text-zinc-900 dark:hover:bg-zinc-200"
              disabled={exporting}
              onClick={() => void handleExportBundle("base")}
            >
              {exporting && exportProgress?.phase !== "Detalii parcele" ? (
                <Loader2 className="mr-2 h-5 w-5 animate-spin" />
              ) : (
                <FileDown className="mr-2 h-5 w-5" />
              )}
              <div className="text-left">
                <div className="font-semibold">
                  Descarcă Terenuri și Clădiri
                </div>
                <div className="text-xs opacity-70 font-normal">
                  Sync + GPKG (din cache dacă e proaspăt)
                </div>
              </div>
            </Button>

            <Button
              size="lg"
              className="h-auto py-4 text-base bg-teal-700 hover:bg-teal-600 text-white dark:bg-teal-600 dark:hover:bg-teal-500"
              disabled={exporting}
              onClick={() => void handleExportBundle("magic")}
            >
              {exporting && exportProgress?.phase === "Detalii parcele" ? (
                <Loader2 className="mr-2 h-5 w-5 animate-spin" />
              ) : (
                <Sparkles className="mr-2 h-5 w-5" />
              )}
              <div className="text-left">
                <div className="font-semibold">Magic</div>
                <div className="text-xs opacity-70 font-normal">
                  Sync + îmbogățire (CF, proprietari, adresă) + GPKG + CSV
                </div>
              </div>
            </Button>
          </div>
        ) : (
          <Card>
            <CardContent className="py-12 text-center text-muted-foreground">
              {!session.connected ? (
                <>
                  <Wifi className="h-10 w-10 mx-auto mb-3 opacity-30" />
                  <p>Conectează-te la eTerra pentru a activa exportul.</p>
                </>
              ) : (
                <>
                  <MapPin className="h-10 w-10 mx-auto mb-3 opacity-30" />
                  <p>Selectează un UAT pentru a activa exportul.</p>
                </>
              )}
            </CardContent>
          </Card>
        )}

        {/* No-geometry option — shown after auto-scan completes */}
        {sirutaValid &&
          session.connected &&
          (() => {
            const scanDone = noGeomScan !== null && noGeomScanSiruta === siruta;
            const estimatedNoGeom = scanDone
              ? Math.max(
                  0,
                  noGeomScan.totalImmovables - noGeomScan.remoteGisCount,
                )
              : 0;
            const hasNoGeomParcels = scanDone && estimatedNoGeom > 0;
            const scanning = noGeomScanning;

            // Still scanning
            if (scanning)
              return (
                <Card className="border-amber-200/50 dark:border-amber-800/50">
                  <CardContent className="py-3 px-4">
                    <div className="flex items-center gap-2 text-sm text-muted-foreground">
                      <Loader2 className="h-4 w-4 animate-spin text-amber-500" />
                      Se scanează lista de imobile din eTerra… (max 2 min)
                    </div>
                    <p className="text-[11px] text-muted-foreground mt-1 ml-6">
                      Poți folosi butoanele de mai jos fără să aștepți scanarea.
                    </p>
                  </CardContent>
                </Card>
              );

            // Scan timed out
            if (scanDone && noGeomScan.scannedAt === "timeout")
              return (
                <Card className="border-amber-200/50 dark:border-amber-800/50">
                  <CardContent className="py-3 px-4">
                    <div className="flex items-center gap-2 text-sm text-amber-600 dark:text-amber-400">
                      <Clock className="h-4 w-4 shrink-0" />
                      Scanarea a depășit 2 minute — serverul eTerra e lent.
                    </div>
                    <p className="text-[11px] text-muted-foreground mt-1 ml-6">
                      Poți lansa sincronizarea fundal fără rezultate de scanare.
                      Include no-geom nu va fi disponibil.
                    </p>
                    <Button
                      variant="ghost"
                      size="sm"
                      className="h-6 text-xs mt-1 ml-6"
                      onClick={() => void handleNoGeomScan()}
                    >
                      <RefreshCw className="h-3 w-3 mr-1" />
                      Reîncearcă scanarea
                    </Button>
                  </CardContent>
                </Card>
              );

            // Helper: local DB status line
            const staleEnrichment =
              scanDone &&
              noGeomScan.localDbEnriched > 0 &&
              noGeomScan.localDbEnrichedComplete < noGeomScan.localDbEnriched;
            const staleCount = scanDone
              ? noGeomScan.localDbEnriched - noGeomScan.localDbEnrichedComplete
              : 0;

            const localDbLine = scanDone && noGeomScan.localDbTotal > 0 && (
              <div className="space-y-0.5 mt-1">
                <div className="flex items-center gap-1.5 flex-wrap text-[11px] text-muted-foreground">
                  <Database className="h-3 w-3 shrink-0" />
                  <span>
                    Baza de date locală:{" "}
                    <span className="font-medium text-foreground">
                      {noGeomScan.localDbWithGeom.toLocaleString("ro-RO")}
                    </span>{" "}
                    cu geometrie
                    {noGeomScan.localDbNoGeom > 0 && (
                      <>
                        {" + "}
                        <span className="font-medium text-amber-600 dark:text-amber-400">
                          {noGeomScan.localDbNoGeom.toLocaleString("ro-RO")}
                        </span>{" "}
                        fără geometrie
                      </>
                    )}
                    {noGeomScan.localDbEnriched > 0 && (
                      <>
                        {" · "}
                        <span className="font-medium text-teal-600 dark:text-teal-400">
                          {noGeomScan.localDbEnriched.toLocaleString("ro-RO")}
                        </span>{" "}
                        îmbogățite
                        {staleEnrichment && (
                          <span className="text-orange-600 dark:text-orange-400">
                            {" "}
                            ({staleCount.toLocaleString("ro-RO")} incomplete)
                          </span>
                        )}
                      </>
                    )}
                    {noGeomScan.localSyncFresh && (
                      <span className="text-emerald-600 dark:text-emerald-400 ml-1">
                        (proaspăt)
                      </span>
                    )}
                  </span>
                </div>
                {staleEnrichment && (
                  <div className="flex items-center gap-1.5 text-[11px] text-orange-600 dark:text-orange-400 ml-[18px]">
                    <AlertTriangle className="h-3 w-3 shrink-0" />
                    <span>
                      {staleCount.toLocaleString("ro-RO")} parcele au îmbogățire
                      veche (lipsă PROPRIETARI_VECHI). Vor fi re-îmbogățite la
                      următorul export Magic.
                    </span>
                  </div>
                )}
              </div>
            );

            // Helper: workflow preview (what Magic will do)
            const workflowPreview = scanDone && (
              <div className="mt-2 ml-7 space-y-0.5">
                <p className="text-[11px] font-medium text-muted-foreground">
                  La apăsarea Magic, pașii vor fi:
                </p>
                <ol className="text-[11px] text-muted-foreground list-decimal ml-4 space-y-px">
                  <li>
                    {"Sync GIS — "}
                    <span
                      className={cn(
                        "font-medium",
                        noGeomScan.localSyncFresh &&
                          noGeomScan.localDbWithGeom > 0
                          ? "text-emerald-600 dark:text-emerald-400"
                          : "text-foreground",
                      )}
                    >
                      {noGeomScan.localSyncFresh &&
                      noGeomScan.localDbWithGeom > 0
                        ? "skip (date proaspete în DB)"
                        : `descarcă ${noGeomScan.remoteGisCount.toLocaleString("ro-RO")} terenuri` +
                          (noGeomScan.remoteCladiriCount > 0
                            ? ` + ${noGeomScan.remoteCladiriCount.toLocaleString("ro-RO")} clădiri`
                            : "")}
                    </span>
                  </li>
                  {includeNoGeom && (
                    <li>
                      Import parcele fără geometrie —{" "}
                      <span className="font-medium text-amber-600 dark:text-amber-400">
                        {(() => {
                          const usefulNoGeom =
                            noGeomScan.qualityBreakdown.useful;
                          const newNoGeom = Math.max(
                            0,
                            usefulNoGeom - noGeomScan.localDbNoGeom,
                          );
                          const filtered = noGeomScan.qualityBreakdown.empty;
                          return newNoGeom > 0
                            ? `~${newNoGeom.toLocaleString("ro-RO")} noi de importat` +
                                (filtered > 0
                                  ? ` (${filtered.toLocaleString("ro-RO")} filtrate)`
                                  : "")
                            : "deja importate";
                        })()}
                      </span>
                    </li>
                  )}
                  <li>
                    Îmbogățire CF, proprietari, adrese —{" "}
                    <span className="font-medium text-teal-600 dark:text-teal-400">
                      {(() => {
                        // What will be in DB after sync + optional no-geom import:
                        // If DB is empty: sync will add remoteGisCount geo features
                        // If DB is fresh: keep localDbTotal
                        const geoAfterSync =
                          noGeomScan.localSyncFresh &&
                          noGeomScan.localDbWithGeom > 0
                            ? noGeomScan.localDbWithGeom
                            : noGeomScan.remoteGisCount;
                        const noGeomAfterImport = includeNoGeom
                          ? Math.max(
                              noGeomScan.localDbNoGeom,
                              noGeomScan.qualityBreakdown.useful,
                            )
                          : noGeomScan.localDbNoGeom;
                        const totalAfter = geoAfterSync + noGeomAfterImport;
                        const remaining =
                          totalAfter - noGeomScan.localDbEnrichedComplete;
                        return remaining > 0
                          ? `~${remaining.toLocaleString("ro-RO")} de procesat (~${Math.ceil((remaining * 0.25) / 60)} min)`
                          : "deja îmbogățite";
                      })()}
                    </span>
                  </li>
                  <li>Generare GPKG + CSV</li>
                  <li>Comprimare ZIP + descărcare</li>
                </ol>
              </div>
            );

            // No-geometry parcels found
            if (hasNoGeomParcels)
              return (
                <Card
                  className={cn(
                    "transition-colors",
                    includeNoGeom
                      ? "border-amber-400 bg-amber-50/50 dark:border-amber-700 dark:bg-amber-950/20"
                      : "border-amber-200 dark:border-amber-800/50",
                  )}
                >
                  <CardContent className="py-3 px-4 space-y-2">
                    <div className="flex items-center gap-3">
                      <AlertTriangle className="h-4 w-4 text-amber-500 shrink-0" />
                      <div className="flex-1 min-w-0">
                        <p className="text-sm">
                          Layer GIS:{" "}
                          <span className="font-semibold">
                            {noGeomScan.remoteGisCount.toLocaleString("ro-RO")}
                          </span>{" "}
                          terenuri
                          {noGeomScan.remoteCladiriCount > 0 && (
                            <>
                              {" + "}
                              <span className="font-semibold">
                                {noGeomScan.remoteCladiriCount.toLocaleString(
                                  "ro-RO",
                                )}
                              </span>{" "}
                              clădiri
                            </>
                          )}
                          {" · "}
                          Lista imobile:{" "}
                          <span className="font-semibold">
                            {noGeomScan.totalImmovables.toLocaleString("ro-RO")}
                          </span>
                          {" (estimat "}
                          <span className="font-semibold text-amber-600 dark:text-amber-400">
                            ~
                            {Math.max(
                              0,
                              noGeomScan.totalImmovables -
                                noGeomScan.remoteGisCount,
                            ).toLocaleString("ro-RO")}
                          </span>
                          {" fără geometrie)"}
                        </p>
                        <p className="text-[11px] text-muted-foreground mt-0.5">
                          Cele fără geometrie există în baza de date eTerra dar
                          nu au contur desenat în layerul GIS.
                        </p>
                        {localDbLine}
                      </div>
                      <Button
                        variant="ghost"
                        size="sm"
                        className="h-7 text-xs shrink-0"
                        disabled={noGeomScanning || exporting}
                        onClick={() => void handleNoGeomScan()}
                        title="Re-scanare"
                      >
                        <RefreshCw className="h-3 w-3" />
                      </Button>
                    </div>
                    <label className="flex items-center gap-2 cursor-pointer select-none ml-7">
                      <input
                        type="checkbox"
                        checked={includeNoGeom}
                        onChange={(e) => setIncludeNoGeom(e.target.checked)}
                        disabled={exporting}
                        className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
                      />
                      <span className="text-sm font-medium">
                        Include și parcelele fără geometrie la export
                      </span>
                    </label>
                    {/* Quality breakdown of no-geom items */}
                    {scanDone && noGeomScan.noGeomCount > 0 && (
                      <div className="ml-7 p-2 rounded-md bg-muted/40 space-y-1">
                        <p className="text-[11px] font-medium text-muted-foreground">
                          Calitate date (din{" "}
                          {noGeomScan.noGeomCount.toLocaleString("ro-RO")} fără
                          geometrie):
                        </p>
                        <div className="grid grid-cols-2 gap-x-4 gap-y-0.5 text-[11px] text-muted-foreground">
                          <span>
                            Cu nr. cadastral eTerra:{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withCadRef.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          <span>
                            Cu nr. CF/LB:{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withPaperLb.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          <span>
                            Cu nr. cad. pe hârtie:{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withPaperCad.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          <span>
                            Cu suprafață:{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withArea.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          <span>
                            Active (status=1):{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withActiveStatus.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          <span>
                            Cu carte funciară:{" "}
                            <span className="font-medium text-foreground">
                              {noGeomScan.qualityBreakdown.withLandbook.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                        </div>
                        <div className="flex items-center gap-3 text-[11px] pt-0.5 border-t border-muted-foreground/10">
                          <span>
                            Utilizabile:{" "}
                            <span className="font-semibold text-emerald-600 dark:text-emerald-400">
                              {noGeomScan.qualityBreakdown.useful.toLocaleString(
                                "ro-RO",
                              )}
                            </span>
                          </span>
                          {noGeomScan.qualityBreakdown.empty > 0 && (
                            <span>
                              Filtrate (fără CF/inactive/fără date):{" "}
                              <span className="font-semibold text-rose-600 dark:text-rose-400">
                                {noGeomScan.qualityBreakdown.empty.toLocaleString(
                                  "ro-RO",
                                )}
                              </span>
                            </span>
                          )}
                        </div>
                      </div>
                    )}
                    {includeNoGeom && (
                      <p className="text-[11px] text-muted-foreground ml-7">
                        {noGeomScan.qualityBreakdown.empty > 0
                          ? `Din ${noGeomScan.noGeomCount.toLocaleString("ro-RO")} fără geometrie, ~${noGeomScan.qualityBreakdown.useful.toLocaleString("ro-RO")} vor fi importate (imobile electronice cu CF). ${noGeomScan.qualityBreakdown.empty.toLocaleString("ro-RO")} vor fi filtrate (fără carte funciară, inactive sau fără date).`
                          : "Vor fi importate în DB și incluse în CSV + Magic GPKG (coloana HAS_GEOMETRY=0/1)."}{" "}
                        În GPKG de bază apar doar cele cu geometrie.
                      </p>
                    )}
                    {workflowPreview}
                  </CardContent>
                </Card>
              );

            // Scan done, all parcels have geometry (or totalImmovables=0 ⇒ workspace issue)
            if (scanDone && !hasNoGeomParcels)
              return (
                <Card className="border-dashed">
                  <CardContent className="py-2.5 px-4">
                    <div className="flex items-center gap-2 text-xs text-muted-foreground">
                      {noGeomScan.totalImmovables > 0 ? (
                        <>
                          <CheckCircle2 className="h-3.5 w-3.5 text-emerald-500" />
                          Toate cele{" "}
                          {noGeomScan.totalImmovables.toLocaleString("ro-RO")}{" "}
                          imobile din eTerra au geometrie — nimic de importat
                          suplimentar.
                          {noGeomScan.localDbTotal > 0 && (
                            <span className="ml-1">
                              ({noGeomScan.localDbTotal.toLocaleString("ro-RO")}{" "}
                              în DB local
                              {noGeomScan.localDbEnriched > 0 &&
                                `, ${noGeomScan.localDbEnriched.toLocaleString("ro-RO")} îmbogățite`}
                              {noGeomScan.localDbEnriched > 0 &&
                                noGeomScan.localDbEnrichedComplete <
                                  noGeomScan.localDbEnriched && (
                                  <span className="text-orange-600 dark:text-orange-400">
                                    {` (${(noGeomScan.localDbEnriched - noGeomScan.localDbEnrichedComplete).toLocaleString("ro-RO")} incomplete)`}
                                  </span>
                                )}
                              {noGeomScan.localSyncFresh && ", proaspăt"})
                            </span>
                          )}
                        </>
                      ) : (
                        <>
                          <AlertTriangle className="h-3.5 w-3.5 text-muted-foreground" />
                          Nu s-au găsit imobile în lista eTerra pentru acest
                          UAT. Verifică sesiunea eTerra.
                        </>
                      )}
                    </div>
                  </CardContent>
                </Card>
              );

            return null;
          })()}

        {/* ── Background sync + Download from DB ──────────────── */}
        {sirutaValid && (
          <Card className="border-dashed">
            <CardContent className="py-3 px-4 space-y-3">
              {/* Row 1: Section label */}
              <div className="flex items-center gap-2">
                <HardDrive className="h-4 w-4 text-muted-foreground" />
                <span className="text-sm font-medium">
                  Procesare fundal &amp; descărcare din DB
                </span>
                <span className="text-[10px] text-muted-foreground">
                  — pornește sincronizarea, închide pagina, descarcă mai târziu
                </span>
              </div>

              {/* Include no-geom toggle (works independently of scan) */}
              {session.connected && (
                <label className="flex items-center gap-2 cursor-pointer select-none ml-6">
                  <input
                    type="checkbox"
                    checked={includeNoGeom}
                    onChange={(e) => setIncludeNoGeom(e.target.checked)}
                    disabled={
                      exporting ||
                      (!!bgJobId && bgProgress?.status === "running")
                    }
                    className="h-4 w-4 rounded border-muted-foreground/30 accent-amber-600"
                  />
                  <span className="text-xs">
                    Include și parcelele fără geometrie
                  </span>
                  {noGeomScanning && (
                    <span className="text-[10px] text-muted-foreground">
                      (scanare în curs…)
                    </span>
                  )}
                </label>
              )}

              {/* Row 2: Background sync buttons */}
              {session.connected && (
                <div className="grid gap-2 sm:grid-cols-2">
                  <Button
                    variant="outline"
                    size="sm"
                    className="h-auto py-2.5 justify-start"
                    disabled={
                      exporting ||
                      (!!bgJobId && bgProgress?.status === "running")
                    }
                    onClick={() => void handleSyncBackground("base")}
                  >
                    {bgJobId &&
                    bgProgress?.status === "running" &&
                    !bgPhaseTrail.some((p) => p.includes("Îmbogățire")) ? (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    ) : (
                      <ArrowDownToLine className="mr-2 h-4 w-4" />
                    )}
                    <div className="text-left">
                      <div className="text-xs font-semibold">
                        Sync fundal — Bază
                      </div>
                      <div className="text-[10px] opacity-60 font-normal">
                        Terenuri + clădiri → salvează în DB
                      </div>
                    </div>
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    className="h-auto py-2.5 justify-start border-teal-200 dark:border-teal-800 hover:bg-teal-50 dark:hover:bg-teal-950/30"
                    disabled={
                      exporting ||
                      (!!bgJobId && bgProgress?.status === "running")
                    }
                    onClick={() => void handleSyncBackground("magic")}
                  >
                    {bgJobId &&
                    bgProgress?.status === "running" &&
                    bgPhaseTrail.some((p) => p.includes("Îmbogățire")) ? (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin text-teal-600" />
                    ) : (
                      <Sparkles className="mr-2 h-4 w-4 text-teal-600" />
                    )}
                    <div className="text-left">
                      <div className="text-xs font-semibold">
                        Sync fundal — Magic
                      </div>
                      <div className="text-[10px] opacity-60 font-normal">
                        Sync + îmbogățire → salvează în DB
                      </div>
                    </div>
                  </Button>
                </div>
              )}

              {/* Row 3: Download from DB buttons */}
              {dbTotalFeatures > 0 && (
                <div className="grid gap-2 sm:grid-cols-2">
                  <Button
                    variant="outline"
                    size="sm"
                    className="h-auto py-2.5 justify-start"
                    disabled={downloadingFromDb}
                    onClick={() => void handleDownloadFromDb("base")}
                  >
                    {downloadingFromDb ? (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin" />
                    ) : (
                      <Database className="mr-2 h-4 w-4" />
                    )}
                    <div className="text-left">
                      <div className="text-xs font-semibold">
                        Descarcă din DB — Bază
                      </div>
                      <div className="text-[10px] opacity-60 font-normal">
                        GPKG terenuri + clădiri (instant, fără eTerra)
                      </div>
                    </div>
                  </Button>
                  <Button
                    variant="outline"
                    size="sm"
                    className="h-auto py-2.5 justify-start border-teal-200 dark:border-teal-800 hover:bg-teal-50 dark:hover:bg-teal-950/30"
                    disabled={downloadingFromDb}
                    onClick={() => void handleDownloadFromDb("magic")}
                  >
                    {downloadingFromDb ? (
                      <Loader2 className="mr-2 h-4 w-4 animate-spin text-teal-600" />
                    ) : (
                      <Sparkles className="mr-2 h-4 w-4 text-teal-600" />
                    )}
                    <div className="text-left">
                      <div className="text-xs font-semibold">
                        Descarcă din DB — Magic
                      </div>
                      <div className="text-[10px] opacity-60 font-normal">
                        GPKG + CSV + raport calitate (instant)
                      </div>
                    </div>
                  </Button>
                </div>
              )}

              {!session.connected && dbTotalFeatures === 0 && (
                <p className="text-xs text-muted-foreground ml-6">
                  Conectează-te la eTerra pentru a porni sincronizarea fundal,
                  sau sincronizează mai întâi date în baza locală.
                </p>
              )}
            </CardContent>
          </Card>
        )}

        {/* Background sync progress */}
        {bgJobId && bgProgress && bgProgress.status !== "unknown" && (
          <Card
            className={cn(
              "border-2 transition-colors",
              bgProgress.status === "running" &&
                "border-indigo-300 dark:border-indigo-700",
              bgProgress.status === "error" &&
                "border-rose-300 dark:border-rose-700",
              bgProgress.status === "done" &&
                "border-emerald-400 dark:border-emerald-600",
            )}
          >
            <CardContent className="pt-4 space-y-3">
              {/* Label */}
              <div className="flex items-center gap-2 text-xs">
                <HardDrive className="h-3.5 w-3.5 text-indigo-500" />
                <span className="font-semibold text-indigo-700 dark:text-indigo-400">
                  Sincronizare fundal
                </span>
                {bgProgress.status === "running" && (
                  <span className="text-muted-foreground">
                    (poți închide pagina)
                  </span>
                )}
              </div>

              {/* Phase trail */}
              <div className="flex items-center gap-2 flex-wrap text-xs text-muted-foreground">
                {bgPhaseTrail.map((p, i) => (
                  <span key={i} className="flex items-center gap-1">
                    {i > 0 && <span className="opacity-40">→</span>}
                    <span
                      className={cn(
                        i === bgPhaseTrail.length - 1
                          ? "font-semibold text-foreground"
                          : "opacity-60",
                      )}
                    >
                      {p}
                    </span>
                  </span>
                ))}
              </div>

              {/* Progress info */}
              <div className="flex items-center gap-3">
                {bgProgress.status === "running" && (
                  <Loader2 className="h-5 w-5 text-indigo-600 animate-spin shrink-0" />
                )}
                {bgProgress.status === "done" && (
                  <CheckCircle2 className="h-5 w-5 text-emerald-600 shrink-0" />
                )}
                {bgProgress.status === "error" && (
                  <XCircle className="h-5 w-5 text-rose-500 shrink-0" />
                )}
                <div className="min-w-0 flex-1">
                  <p className="text-sm font-medium">{bgProgress.phase}</p>
                  {bgProgress.note && (
                    <p className="text-xs text-muted-foreground">
                      {bgProgress.note}
                    </p>
                  )}
                  {bgProgress.message && (
                    <p
                      className={cn(
                        "text-xs mt-0.5",
                        bgProgress.status === "error"
                          ? "text-rose-500"
                          : "text-muted-foreground",
                      )}
                    >
                      {bgProgress.message}
                    </p>
                  )}
                </div>
                <span className="text-sm font-mono font-semibold tabular-nums shrink-0">
                  {bgProgress.total && bgProgress.total > 0
                    ? Math.round(
                        (bgProgress.downloaded / bgProgress.total) * 100,
                      )
                    : 0}
                  %
                </span>
              </div>

              {/* Bar */}
              <div className="h-2.5 w-full rounded-full bg-muted">
                <div
                  className={cn(
                    "h-2.5 rounded-full transition-all duration-300",
                    bgProgress.status === "running" && "bg-indigo-500",
                    bgProgress.status === "done" && "bg-emerald-500",
                    bgProgress.status === "error" && "bg-rose-500",
                  )}
                  style={{
                    width: `${Math.max(2, bgProgress.total && bgProgress.total > 0 ? Math.round((bgProgress.downloaded / bgProgress.total) * 100) : 0)}%`,
                  }}
                />
              </div>

              {/* Done — show download from DB button */}
              {bgProgress.status === "done" && (
                <div className="flex gap-2 pt-1">
                  <Button
                    variant="outline"
                    size="sm"
                    className="text-xs border-teal-200 dark:border-teal-800"
                    disabled={downloadingFromDb}
                    onClick={() => void handleDownloadFromDb("magic")}
                  >
                    {downloadingFromDb ? (
                      <Loader2 className="mr-1.5 h-3 w-3 animate-spin" />
                    ) : (
                      <Database className="mr-1.5 h-3 w-3" />
                    )}
                    Descarcă din DB (Magic)
                  </Button>
                  <Button
                    variant="ghost"
                    size="sm"
                    className="text-xs"
                    onClick={() => {
                      setBgJobId(null);
                      setBgProgress(null);
                      setBgPhaseTrail([]);
                    }}
                  >
                    Închide
                  </Button>
                </div>
              )}
            </CardContent>
          </Card>
        )}

        {/* Progress bar */}
        {exportProgress &&
          exportProgress.status !== "unknown" &&
          exportJobId && (
            <Card
              className={cn(
                "border-2 transition-colors",
                exportProgress.status === "running" &&
                  "border-emerald-300 dark:border-emerald-700",
                exportProgress.status === "error" &&
                  "border-rose-300 dark:border-rose-700",
                exportProgress.status === "done" &&
                  "border-emerald-400 dark:border-emerald-600",
              )}
            >
              <CardContent className="pt-4 space-y-3">
                {/* Phase trail */}
                <div className="flex items-center gap-2 flex-wrap text-xs text-muted-foreground">
                  {phaseTrail.map((p, i) => (
                    <span key={i} className="flex items-center gap-1">
                      {i > 0 && <span className="opacity-40">→</span>}
                      <span
                        className={cn(
                          i === phaseTrail.length - 1
                            ? "font-semibold text-foreground"
                            : "opacity-60",
                        )}
                      >
                        {p}
                      </span>
                    </span>
                  ))}
                </div>

                {/* Progress info */}
                <div className="flex items-center gap-3">
                  {exportProgress.status === "running" && (
                    <Loader2 className="h-5 w-5 text-emerald-600 animate-spin shrink-0" />
                  )}
                  {exportProgress.status === "done" && (
                    <CheckCircle2 className="h-5 w-5 text-emerald-600 shrink-0" />
                  )}
                  {exportProgress.status === "error" && (
                    <XCircle className="h-5 w-5 text-rose-500 shrink-0" />
                  )}
                  <div className="min-w-0 flex-1">
                    <p className="text-sm font-medium">
                      {exportProgress.phase}
                      {exportProgress.phaseCurrent != null &&
                      exportProgress.phaseTotal
                        ? ` — ${exportProgress.phaseCurrent} / ${exportProgress.phaseTotal}`
                        : ""}
                    </p>
                    {exportProgress.note && (
                      <p className="text-xs text-muted-foreground">
                        {exportProgress.note}
                      </p>
                    )}
                    {exportProgress.message && (
                      <p
                        className={cn(
                          "text-xs mt-0.5",
                          exportProgress.status === "error"
                            ? "text-rose-500"
                            : "text-muted-foreground",
                        )}
                      >
                        {exportProgress.message}
                      </p>
                    )}
                  </div>
                  <span className="text-sm font-mono font-semibold tabular-nums shrink-0">
                    {progressPct}%
                  </span>
                </div>

                {/* Bar */}
                <div className="h-2.5 w-full rounded-full bg-muted">
                  <div
                    className={cn(
                      "h-2.5 rounded-full transition-all duration-300",
                      exportProgress.status === "running" && "bg-emerald-500",
                      exportProgress.status === "done" && "bg-emerald-500",
                      exportProgress.status === "error" && "bg-rose-500",
                    )}
                    style={{ width: `${Math.max(2, progressPct)}%` }}
                  />
                </div>
              </CardContent>
            </Card>
          )}
      </TabsContent>

      {/* ═══════════════════════════════════════════════════════ */}
      {/*  Tab 4: Baza de Date                                     */}
      {/* ═══════════════════════════════════════════════════════ */}
      <TabsContent value="database" className="space-y-3">
        {dbSummaryLoading && !dbSummary ? (
          <Card>
            <CardContent className="py-12 text-center text-muted-foreground">
              <Loader2 className="h-8 w-8 mx-auto mb-3 animate-spin opacity-40" />
              <p>Se încarcă datele din baza de date…</p>
            </CardContent>
          </Card>
        ) : !dbSummary || dbSummary.totalFeatures === 0 ? (
          <Card>
            <CardContent className="py-12 text-center text-muted-foreground">
              <Database className="h-10 w-10 mx-auto mb-3 opacity-30" />
              <p className="font-medium">Nicio dată în baza de date</p>
              <p className="text-xs mt-1">
                Folosește tab-ul Export pentru a sincroniza date din eTerra.
              </p>
            </CardContent>
          </Card>
        ) : (
          <>
            {/* Header row */}
            <div className="flex items-center justify-between gap-3">
              <div className="flex items-center gap-2">
                <Database className="h-4 w-4 text-muted-foreground" />
                <span className="text-sm font-medium">
                  {dbSummary.totalFeatures.toLocaleString("ro-RO")} entități
                </span>
                <span className="text-xs text-muted-foreground">
                  din {dbSummary.totalUats} UAT-uri
                </span>
              </div>
              <Button
                variant="ghost"
                size="sm"
                className="h-7 text-xs"
                disabled={dbSummaryLoading}
                onClick={() => void fetchDbSummary()}
              >
                {dbSummaryLoading ? (
                  <Loader2 className="h-3 w-3 mr-1 animate-spin" />
                ) : (
                  <RefreshCw className="h-3 w-3 mr-1" />
                )}
                Reîncarcă
              </Button>
            </div>

            {/* UAT cards */}
            {dbSummary.uats.map((uat) => {
              const catCounts: Record<string, number> = {};
              let enrichedTotal = 0;
              let noGeomTotal = 0;
              let oldestSync: Date | null = null;
              for (const layer of uat.layers) {
                const cat =
                  findLayerById(layer.layerId)?.category ?? "administrativ";
                catCounts[cat] = (catCounts[cat] ?? 0) + layer.count;
                enrichedTotal += layer.enrichedCount;
                noGeomTotal += layer.noGeomCount ?? 0;
                if (layer.lastSynced) {
                  const d = new Date(layer.lastSynced);
                  if (!oldestSync || d < oldestSync) oldestSync = d;
                }
              }
              const isCurrentUat = sirutaValid && uat.siruta === siruta;

              return (
                <div key={uat.siruta} className="space-y-3">
                  <Card
                    className={cn(
                      "transition-colors",
                      isCurrentUat && "ring-1 ring-emerald-400/50",
                    )}
                  >
                    <CardContent className="py-3 px-4 space-y-2">
                      {/* UAT header row */}
                      <div className="flex items-center gap-2 flex-wrap">
                        <span className="text-sm font-semibold">
                          {uat.uatName}
                        </span>
                        {uat.county && (
                          <span className="text-[10px] text-muted-foreground">
                            ({uat.county})
                          </span>
                        )}
                        <span className="text-[10px] font-mono text-muted-foreground">
                          #{uat.siruta}
                        </span>
                        {isCurrentUat && (
                          <Badge
                            variant="outline"
                            className="text-[9px] h-4 text-emerald-600 border-emerald-300 dark:text-emerald-400 dark:border-emerald-700"
                          >
                            selectat
                          </Badge>
                        )}
                        <span className="ml-auto flex items-center gap-2">
                          <Button
                            variant="ghost"
                            size="sm"
                            className="h-5 px-2 text-[10px] gap-1 text-indigo-600 dark:text-indigo-400 hover:text-indigo-700 hover:bg-indigo-50 dark:hover:bg-indigo-950"
                            onClick={() =>
                              setDashboardSiruta(
                                dashboardSiruta === uat.siruta
                                  ? null
                                  : uat.siruta,
                              )
                            }
                          >
                            <BarChart3 className="h-3 w-3" />
                            Dashboard
                          </Button>
                          <span className="text-xs text-muted-foreground">
                            {oldestSync ? relativeTime(oldestSync) : "—"}
                          </span>
                        </span>
                      </div>

                      {/* Category counts in a single compact row */}
                      <div className="flex items-center gap-2 flex-wrap text-xs">
                        {(
                          Object.entries(LAYER_CATEGORY_LABELS) as [
                            LayerCategory,
                            string,
                          ][]
                        ).map(([cat, label]) => {
                          const count = catCounts[cat] ?? 0;
                          if (count === 0) return null;
                          return (
                            <span
                              key={cat}
                              className="inline-flex items-center gap-1"
                            >
                              <span className="text-muted-foreground">
                                {label}:
                              </span>
                              <span className="font-medium tabular-nums">
                                {count.toLocaleString("ro-RO")}
                              </span>
                            </span>
                          );
                        })}
                        {enrichedTotal > 0 && (
                          <span className="inline-flex items-center gap-1">
                            <Sparkles className="h-3 w-3 text-teal-600 dark:text-teal-400" />
                            <span className="text-muted-foreground">
                              Magic:
                            </span>
                            <span className="font-medium tabular-nums text-teal-700 dark:text-teal-400">
                              {enrichedTotal.toLocaleString("ro-RO")}
                            </span>
                          </span>
                        )}
                        {noGeomTotal > 0 && (
                          <span className="inline-flex items-center gap-1">
                            <span className="text-muted-foreground">
                              Fără geom:
                            </span>
                            <span className="font-medium tabular-nums text-amber-600 dark:text-amber-400">
                              {noGeomTotal.toLocaleString("ro-RO")}
                            </span>
                          </span>
                        )}
                      </div>

                      {/* Layer detail pills */}
                      <div className="flex gap-1.5 flex-wrap">
                        {uat.layers
                          .sort((a, b) => b.count - a.count)
                          .map((layer) => {
                            const meta = findLayerById(layer.layerId);
                            const label =
                              meta?.label ?? layer.layerId.replace(/_/g, " ");
                            const isEnriched = layer.enrichedCount > 0;
                            return (
                              <span
                                key={layer.layerId}
                                className={cn(
                                  "inline-flex items-center gap-1 rounded-md border px-1.5 py-0.5 text-[10px]",
                                  isEnriched
                                    ? "border-teal-200 bg-teal-50/50 dark:border-teal-800 dark:bg-teal-950/30"
                                    : "border-muted bg-muted/30",
                                )}
                                title={`${label}: ${layer.count} entități${isEnriched ? `, ${layer.enrichedCount} îmbogățite` : ""}${layer.lastSynced ? `, sync: ${new Date(layer.lastSynced).toLocaleDateString("ro-RO")}` : ""}`}
                              >
                                <span className="truncate max-w-[120px]">
                                  {label}
                                </span>
                                <span className="font-medium tabular-nums">
                                  {layer.count.toLocaleString("ro-RO")}
                                </span>
                                {isEnriched && (
                                  <Sparkles className="h-2.5 w-2.5 text-teal-600 dark:text-teal-400" />
                                )}
                              </span>
                            );
                          })}
                      </div>
                    </CardContent>
                  </Card>

                  {/* Dashboard panel (expanded below card) */}
                  {dashboardSiruta === uat.siruta && (
                    <UatDashboard
                      siruta={uat.siruta}
                      uatName={uat.uatName}
                      onClose={() => setDashboardSiruta(null)}
                    />
                  )}
                </div>
              );
            })}
          </>
        )}
      </TabsContent>
    </Tabs>
  );
}
