"use client";

import { useEffect, useRef, useState } from "react";
import {
  Boxes,
  ChevronRight,
  Eraser,
  FileDown,
  FileUp,
  Folder,
  Grid3x3,
  HelpCircle,
  Layers,
  Loader2,
  MoreHorizontal,
  Package,
  PackagePlus,
  Play,
  Redo2,
  RotateCw,
  FlipHorizontal2,
  FlipVertical2,
  Undo2,
  X,
  Check,
} from "lucide-react";
import { useDiagramStore } from "@/store/diagramStore";
import MultiRunPanel from "@/components/panels/MultiRunPanel";
import CreateModuleModal from "@/components/modals/CreateModuleModal";
import WorkspaceHelpModal from "@/components/modals/WorkspaceHelpModal";
import type { NewDocumentKind } from "@/components/modals/NewModelModal";

/** UI Load menu — only configs that converge via POST /api/simulate. */
const EXAMPLES = [
  { file: "hx_air_water_4port.json", label: "HX air–water" },
  { file: "chiller_flooded_4port_watercooled.json", label: "Chiller flooded" },
  { file: "chiller_watercooled_r410a.json", label: "Chiller R410A" },
  { file: "chiller_aircooled_r134a.json", label: "Chiller air-cooled" },
  { file: "chiller_aircooled_r134a_fan.json", label: "Chiller air-cooled + fan" },
  { file: "bphx_evaporator_condenser.json", label: "BPHX cycle" },
  { file: "heatpump_r410a_reversing_valve.json", label: "Heat pump 4-way" },
  { file: "chiller_r134a_exv_orifice.json", label: "EXV orifice" },
  { file: "chiller_r410a_full_physics.json", label: "R410A full physics" },
  // Not listed (not executable yet):
  // - capillary_tube_r134a.json — CapillaryTube graph residuals are stubs (singular Jacobian)
];

interface TopBarProps {
  /** Breadcrumb path, e.g. ["Untitled"] or ["Untitled", "BaseChiller"]. */
  scope: string[];
  unsaved?: boolean;
  editingModule?: string | null;
  workspaceName?: string;
  onNavigateBack?: () => void;
  onExitModuleEditor?: () => void;
  onSaveModuleEditor?: () => void;
  onOpenNew?: (kind?: NewDocumentKind) => void;
  onSimulate?: () => void;
  simulating?: boolean;
}

/**
 * Workbench toolbar — classes are the primary document type.
 *
 *   LEFT:  brand · Nouveau modèle · Import · Save as class
 *   CENTER: WorkspaceName › ClassName.ekmod  (+ Save/Quit when editing)
 *   RIGHT: undo · transform · examples · Solve
 */
export default function TopBar({
  scope,
  unsaved,
  editingModule,
  workspaceName = "Workspace",
  onNavigateBack,
  onExitModuleEditor,
  onSaveModuleEditor,
  onOpenNew,
  onSimulate,
  simulating = false,
}: TopBarProps) {
  const {
    snapToGrid,
    selectedNodeId,
    toggleSnapToGrid,
    rotateNode,
    flipNodeH,
    flipNodeV,
    loadFromConfig,
    clear,
  } = useDiagramStore();

  const canUndo = useDiagramStore((s) => s.canUndo);
  const canRedo = useDiagramStore((s) => s.canRedo);
  const undo = useDiagramStore((s) => s.undo);
  const redo = useDiagramStore((s) => s.redo);

  const [issues, setIssues] = useState<string[]>([]);
  const [moreOpen, setMoreOpen] = useState(false);
  const [multiOpen, setMultiOpen] = useState(false);
  const [createModuleOpen, setCreateModuleOpen] = useState(false);
  const [helpOpen, setHelpOpen] = useState(false);
  const [confirmClear, setConfirmClear] = useState(false);
  const [exampleFile, setExampleFile] = useState(EXAMPLES[0].file);
  const fileInputRef = useRef<HTMLInputElement | null>(null);

  const onLoadExample = async () => {
    try {
      const res = await fetch(`/examples/${exampleFile}`);
      if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
      loadFromConfig(await res.json());
      setIssues([]);
    } catch (e) {
      setIssues([`Could not load example: ${e instanceof Error ? e.message : e}`]);
    }
  };

  const onImportJsonFile = async (file: File | undefined) => {
    if (!file) return;
    try {
      const text = await file.text();
      loadFromConfig(JSON.parse(text));
      setIssues([]);
    } catch (e) {
      setIssues([`Could not import JSON: ${e instanceof Error ? e.message : e}`]);
    } finally {
      if (fileInputRef.current) fileInputRef.current.value = "";
    }
  };

  useEffect(() => {
    const onKey = (e: KeyboardEvent) => {
      const target = e.target as HTMLElement | null;
      const tag = target?.tagName;
      const typing =
        !!target &&
        (tag === "TEXTAREA" ||
          tag === "SELECT" ||
          target.isContentEditable ||
          (tag === "INPUT" &&
            (target as HTMLInputElement).type !== "checkbox" &&
            (target as HTMLInputElement).type !== "radio"));

      if ((e.ctrlKey || e.metaKey) && (e.key === "n" || e.key === "N")) {
        e.preventDefault();
        onOpenNew?.("class");
        return;
      }
      if ((e.ctrlKey || e.metaKey) && (e.key === "s" || e.key === "S")) {
        e.preventDefault();
        if (editingModule && onSaveModuleEditor) onSaveModuleEditor();
        else if (!typing) setCreateModuleOpen(true);
        return;
      }
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [onOpenNew, editingModule, onSaveModuleEditor]);

  // Escape cancels the "Clear workspace" confirmation dialog.
  useEffect(() => {
    if (!confirmClear) return;
    const onKey = (e: KeyboardEvent) => {
      if (e.key === "Escape") setConfirmClear(false);
    };
    window.addEventListener("keydown", onKey);
    return () => window.removeEventListener("keydown", onKey);
  }, [confirmClear]);

  const parents = scope.length > 1 ? scope.slice(0, -1) : [];
  const active = scope.length > 0 ? scope[scope.length - 1] : null;
  const showClassInScope = !!editingModule;

  return (
    <>
      <header className="flex h-11 items-center gap-2 border-b border-[var(--line)] bg-[var(--chrome)] px-3">
        <div className="flex items-center gap-2 pr-1">
          <Boxes size={16} className="text-[var(--accent)]" />
          <span className="mono text-[12px] font-semibold tracking-[0.12em] text-[var(--ink)]">
            ENTROPYK
          </span>
        </div>

        <div className="h-5 w-px bg-[var(--line)]" />

        {onOpenNew && (
          <button
            type="button"
            onClick={() => onOpenNew("class")}
            className="flex items-center gap-1.5 rounded-md bg-[var(--accent)] px-2.5 py-1.5 text-[11px] font-semibold text-white shadow-sm hover:bg-[var(--accent-hover,#1d4ed8)]"
            title="Nouveau modèle dans le Workspace (Ctrl+N)"
          >
            <PackagePlus size={13} />
            Nouveau modèle
          </button>
        )}

        {editingModule && (
          <div className="flex items-center gap-1.5 rounded-md border border-[var(--accent)]/30 bg-[var(--accent-subtle,#eff6ff)] px-2 py-1">
            <Package size={13} className="text-[var(--accent)]" />
            <span className="mono text-[12px] font-semibold text-[var(--ink)]">
              {editingModule}
            </span>
            <span className="mono text-[10px] text-[var(--ink-faint)]">.ekmod</span>
            {unsaved && (
              <span className="h-1.5 w-1.5 rounded-full bg-[var(--warn)]" title="Unsaved changes" />
            )}
            {onSaveModuleEditor && (
              <button
                type="button"
                onClick={onSaveModuleEditor}
                className="ml-1 flex items-center gap-1 rounded bg-[var(--accent)] px-2 py-0.5 text-[10px] font-semibold text-white hover:opacity-90"
                title="Save class (Ctrl+S)"
              >
                <Check size={10} /> Save
              </button>
            )}
            {onExitModuleEditor && (
              <button
                type="button"
                onClick={onExitModuleEditor}
                className="flex items-center gap-1 rounded px-2 py-0.5 text-[10px] font-medium text-[var(--ink-dim)] hover:bg-white"
                title="Close class tab"
              >
                <X size={10} /> Close
              </button>
            )}
          </div>
        )}

        <button
          type="button"
          onClick={() => fileInputRef.current?.click()}
          className="flex items-center gap-1 rounded-md border border-[var(--line)] bg-white px-2 py-1.5 text-[11px] font-medium text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
          title="Import a ScenarioConfig JSON"
        >
          <FileUp size={13} /> Import
        </button>

        {!editingModule && (
          <button
            type="button"
            onClick={() => setCreateModuleOpen(true)}
            className="flex items-center gap-1 rounded-md border border-[var(--line)] bg-white px-2 py-1.5 text-[11px] font-medium text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
            title="Save current diagram as a class (.ekmod)"
          >
            <PackagePlus size={13} className="text-[var(--accent)]" /> Save as class
          </button>
        )}

        <input
          ref={fileInputRef}
          type="file"
          accept="application/json,.json"
          className="hidden"
          onChange={(event) => void onImportJsonFile(event.target.files?.[0])}
        />

        <div className="h-5 w-px bg-[var(--line)]" />

        {/* Scope — always show workspace name; class when editing */}
        <nav className="flex min-w-0 items-center gap-1 text-[12px]" aria-label="Document scope">
          <button
            type="button"
            onClick={onNavigateBack}
            disabled={!showClassInScope}
            className={`flex items-center gap-1.5 rounded px-1.5 py-0.5 font-medium transition-colors ${
              showClassInScope
                ? "text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] hover:text-[var(--ink)]"
                : "cursor-default text-[var(--ink)]"
            }`}
            title={showClassInScope ? "Back to Workspace" : "Workspace"}
          >
            <Folder size={13} className="text-[var(--accent)]" />
            <span className="truncate font-semibold">
              {workspaceName === "Untitled" ? "Workspace" : workspaceName}
            </span>
          </button>

          {showClassInScope && editingModule && (
            <span className="flex min-w-0 items-center gap-1">
              <ChevronRight size={12} className="shrink-0 text-[var(--ink-muted,#b7c0ca)]" />
              <Package size={12} className="shrink-0 text-[var(--accent)]" />
              <span className="mono truncate font-semibold text-[var(--ink)]">{editingModule}</span>
              <span className="mono shrink-0 text-[10px] text-[var(--ink-faint)]">.ekmod</span>
              {unsaved && (
                <span className="h-1.5 w-1.5 shrink-0 rounded-full bg-[var(--warn)]" title="Unsaved" />
              )}
            </span>
          )}

        </nav>

        {issues.length > 0 && (
          <span
            className="mono ml-1 max-w-[200px] truncate rounded bg-[var(--warn-subtle,#fffbeb)] px-2 py-0.5 text-[10px] text-[var(--warn)]"
            title={issues.join("\n")}
          >
            {issues[0]}
          </span>
        )}

        <div className="flex-1" />

        <div className="flex items-center gap-0.5">
          <button
            type="button"
            onClick={undo}
            disabled={!canUndo}
            className="grid h-7 w-7 place-items-center rounded text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] disabled:opacity-35"
            title="Undo (Ctrl+Z)"
          >
            <Undo2 size={13} />
          </button>
          <button
            type="button"
            onClick={redo}
            disabled={!canRedo}
            className="grid h-7 w-7 place-items-center rounded text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] disabled:opacity-35"
            title="Redo (Ctrl+Y)"
          >
            <Redo2 size={13} />
          </button>
        </div>

        <div className="h-5 w-px bg-[var(--line)]" />

        <div className="flex items-center overflow-hidden rounded-md border border-[var(--line)] bg-white">
          <button
            type="button"
            onClick={() => selectedNodeId && rotateNode(selectedNodeId, 1)}
            disabled={!selectedNodeId}
            className="grid h-7 w-7 place-items-center text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] disabled:opacity-35"
            title="Rotate 90° (R)"
          >
            <RotateCw size={13} />
          </button>
          <button
            type="button"
            onClick={() => selectedNodeId && flipNodeH(selectedNodeId)}
            disabled={!selectedNodeId}
            className="grid h-7 w-7 place-items-center border-l border-[var(--line)] text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] disabled:opacity-35"
            title="Flip horizontal (H)"
          >
            <FlipHorizontal2 size={13} />
          </button>
          <button
            type="button"
            onClick={() => selectedNodeId && flipNodeV(selectedNodeId)}
            disabled={!selectedNodeId}
            className="grid h-7 w-7 place-items-center border-l border-[var(--line)] text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] disabled:opacity-35"
            title="Flip vertical (V)"
          >
            <FlipVertical2 size={13} />
          </button>
          <button
            type="button"
            onClick={toggleSnapToGrid}
            className={`grid h-7 w-7 place-items-center border-l border-[var(--line)] ${
              snapToGrid
                ? "bg-[var(--accent-subtle,#eff6ff)] text-[var(--accent)]"
                : "text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
            }`}
            title="Snap to grid"
          >
            <Grid3x3 size={13} />
          </button>
        </div>

        <div className="h-5 w-px bg-[var(--line)]" />

        <select
          value={exampleFile}
          onChange={(e) => setExampleFile(e.target.value)}
          className="mono max-w-[140px] rounded-md border border-[var(--line)] bg-white px-1.5 py-1 text-[11px] text-[var(--ink-dim)] outline-none focus:border-[var(--accent)]"
          title="Example scenario"
        >
          {EXAMPLES.map((ex) => (
            <option key={ex.file} value={ex.file}>
              {ex.label}
            </option>
          ))}
        </select>
        <button
          type="button"
          onClick={onLoadExample}
          className="flex items-center gap-1 rounded-md border border-[var(--line)] bg-white px-2 py-1.5 text-[11px] font-medium text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
          title="Load selected example into the scenario"
        >
          <FileDown size={13} /> Load
        </button>

        <div className="relative">
          <button
            type="button"
            onClick={() => setMoreOpen((v) => !v)}
            className="grid h-7 w-7 place-items-center rounded text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
            title="More actions"
            aria-haspopup="menu"
            aria-expanded={moreOpen}
          >
            <MoreHorizontal size={14} />
          </button>
          {moreOpen && (
            <>
              <div
                className="fixed inset-0 z-10"
                onClick={() => setMoreOpen(false)}
                aria-hidden="true"
              />
              <div
                role="menu"
                className="absolute right-0 top-full z-20 mt-1 w-56 overflow-hidden rounded-md border border-[var(--line)] bg-white py-1 text-[12px] shadow-md"
              >
                <MenuItem
                  icon={<Layers size={13} />}
                  label="Multi-run sweep…"
                  onClick={() => {
                    setMoreOpen(false);
                    setMultiOpen(true);
                  }}
                />
                <MenuItem
                  icon={<HelpCircle size={13} />}
                  label="Guide & help"
                  onClick={() => {
                    setMoreOpen(false);
                    setHelpOpen(true);
                  }}
                />
                <div className="my-1 h-px bg-[var(--line)]" />
                <MenuItem
                  icon={<Eraser size={13} />}
                  label="Clear workspace"
                  onClick={() => {
                    setMoreOpen(false);
                    setConfirmClear(true);
                  }}
                  danger
                />
              </div>
            </>
          )}
        </div>

        <div className="h-5 w-px bg-[var(--line)]" />

        <button
          type="button"
          onClick={onSimulate}
          disabled={simulating}
          className="flex items-center gap-1.5 rounded-md bg-[var(--accent)] px-3 py-1.5 text-[11px] font-semibold text-white shadow-sm hover:bg-[var(--accent-hover,#1d4ed8)] disabled:opacity-50"
          title="Solve scenario (Ctrl+Enter)"
        >
          {simulating ? (
            <Loader2 size={13} className="animate-spin" />
          ) : (
            <Play size={13} className="fill-current" />
          )}
          {simulating ? "Solving…" : "Solve"}
        </button>
      </header>

      {multiOpen && <MultiRunPanel onClose={() => setMultiOpen(false)} />}
      {createModuleOpen && (
        <CreateModuleModal
          isOpen={createModuleOpen}
          onClose={() => setCreateModuleOpen(false)}
        />
      )}
      {helpOpen && (
        <WorkspaceHelpModal isOpen={helpOpen} onClose={() => setHelpOpen(false)} />
      )}
      {confirmClear && (
        <div
          className="fixed inset-0 z-50 flex items-center justify-center bg-black/40 p-4 overscroll-contain"
          role="dialog"
          aria-modal="true"
          aria-label="Confirmer l'effacement"
        >
          <div className="w-full max-w-sm rounded-lg border border-[var(--line)] bg-[var(--panel)] p-4 shadow-xl">
            <p className="text-[13px] font-semibold text-[var(--ink)]">
              Effacer tout le schéma ?
            </p>
            <p className="mt-1 text-[11px] text-[var(--ink-dim)]">
              Cette action est irréversible.
            </p>
            <div className="mt-3 flex justify-end gap-2">
              <button
                type="button"
                onClick={() => setConfirmClear(false)}
                className="rounded-md border border-[var(--line)] bg-white px-3 py-1.5 text-[11px] font-medium text-[var(--ink-dim)] hover:bg-[var(--chrome-2)]"
              >
                Annuler
              </button>
              <button
                type="button"
                onClick={() => {
                  clear();
                  setConfirmClear(false);
                }}
                className="rounded-md bg-[var(--warn)] px-3 py-1.5 text-[11px] font-semibold text-white hover:opacity-90"
              >
                Effacer
              </button>
            </div>
          </div>
        </div>
      )}
    </>
  );
}

function MenuItem({
  icon,
  label,
  onClick,
  danger,
}: {
  icon: React.ReactNode;
  label: string;
  onClick?: () => void;
  danger?: boolean;
}) {
  return (
    <button
      type="button"
      role="menuitem"
      onClick={onClick}
      className={`flex w-full items-center gap-2.5 px-3 py-1.5 text-left transition-colors ${
        danger
          ? "text-[var(--hot)] hover:bg-[var(--hot-subtle,#fef2f2)]"
          : "text-[var(--ink-dim)] hover:bg-[var(--chrome-2)] hover:text-[var(--ink)]"
      }`}
    >
      <span className="shrink-0 opacity-80">{icon}</span>
      <span className="flex-1 truncate">{label}</span>
    </button>
  );
}
