import { useRef, useState, useEffect } from 'react';
import { useBuilder } from '../store/builderStore';
import type { RenderMode, ViewMode, PlacedPart } from '../types';
import {
  downloadProject,
  importProjectFile,
} from '../utils/serializer';
import { useAuth } from '../auth/AuthContext';
import { PaywallModal } from '../payments/PaywallModal';
import { addToast } from './Toast';
import { useSaveStatus } from '../store/saveStatusStore';

function SaveIndicator() {
  const status = useSaveStatus((s) => s.status);
  if (status === 'saved') {
    return (
      <span
        title="All changes saved to browser"
        className="h-2 w-2 rounded-full bg-emerald-500 transition-colors duration-300 shrink-0"
      />
    );
  }
  if (status === 'saving') {
    return (
      <span
        title="Saving changes..."
        className="h-2 w-2 rounded-full bg-amber-500 animate-pulse shrink-0"
      />
    );
  }
  return (
    <span
      title="Unsaved changes"
      className="h-2 w-2 rounded-full bg-amber-500 shrink-0"
    />
  );
}

/**
 * Toolbar — project actions (new/save/load/export/import), undo/redo,
 * tools (measure, snap), view presets, and the flow-animation toggle.
 */
export function Toolbar({
  onOpenBom,
  onCheckBuild,
}: {
  onOpenBom: () => void;
  onCheckBuild: () => void;
}) {
  const { token, user, logout, refreshProfile } = useAuth();
  const [showPaywall, setShowPaywall] = useState(false);
  const [projectsList, setProjectsList] = useState<{ name: string; savedAt: string; parts: PlacedPart[] }[]>([]);
  const [loadingProjects, setLoadingProjects] = useState(false);

  const projectName = useBuilder((s) => s.projectName);
  const setProjectName = useBuilder((s) => s.setProjectName);
  const growthStage = useBuilder((s) => s.growthStage);
  const setGrowthStage = useBuilder((s) => s.setGrowthStage);
  const viewMode = useBuilder((s) => s.viewMode);
  const setViewMode = useBuilder((s) => s.setViewMode);
  const renderMode = useBuilder((s) => s.renderMode);
  const setRenderMode = useBuilder((s) => s.setRenderMode);
  const tool = useBuilder((s) => s.tool);
  const setTool = useBuilder((s) => s.setTool);
  const showFlow = useBuilder((s) => s.showFlow);
  const toggleFlow = useBuilder((s) => s.toggleFlow);
  const simRunning = useBuilder((s) => s.simRunning);
  const toggleSimRunning = useBuilder((s) => s.toggleSimRunning);
  const snapToGrid = useBuilder((s) => s.snapToGrid);
  const toggleSnap = useBuilder((s) => s.toggleSnap);
  const undo = useBuilder((s) => s.undo);
  const redo = useBuilder((s) => s.redo);
  const canUndo = useBuilder((s) => s.past.length > 0);
  const canRedo = useBuilder((s) => s.future.length > 0);
  const autoCapOpenEnds = useBuilder((s) => s.autoCapOpenEnds);
  const rooms = useBuilder((s) => s.rooms);
  const activeRoomId = useBuilder((s) => s.activeRoomId);
  const addRoom = useBuilder((s) => s.addRoom);
  const removeRoom = useBuilder((s) => s.removeRoom);
  const setActiveRoomId = useBuilder((s) => s.setActiveRoomId);

  const fileRef = useRef<HTMLInputElement>(null);
  const [loadOpen, setLoadOpen] = useState(false);
  const [showShortcuts, setShowShortcuts] = useState(false);

  const fetchProjects = async () => {
    if (!token) return;
    setLoadingProjects(true);
    try {
      const response = await fetch('/api/projects', {
        headers: { Authorization: `Bearer ${token}` }
      });
      if (response.ok) {
        const data = await response.json();
        setProjectsList(data);
      }
    } catch (err) {
      console.error('Failed to fetch projects', err);
    } finally {
      setLoadingProjects(false);
    }
  };

  useEffect(() => {
    if (loadOpen) {
      void fetchProjects();
    }
  }, [loadOpen]);

  const handleSave = async () => {
    if (!token) return;
    const s = useBuilder.getState();
    const partsArray = Object.values(s.parts);

    try {
      const response = await fetch('/api/projects', {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json',
          Authorization: `Bearer ${token}`
        },
        body: JSON.stringify({ name: s.projectName, parts: partsArray })
      });

      const data = await response.json();

      if (!response.ok) {
        if (response.status === 402) {
          setShowPaywall(true);
        } else {
          addToast(data.error || 'Failed to save project', 'error');
        }
        return;
      }

      await refreshProfile();
      addToast('Project saved successfully!', 'success');
    } catch (err) {
      addToast('Save failed: ' + err, 'error');
    }
  };

  const handleLoad = (name: string) => {
    const proj = projectsList.find((p) => p.name === name);
    if (proj) {
      useBuilder.getState().loadParts(proj.parts, proj.name);
    }
    setLoadOpen(false);
  };

  const handleDelete = async (e: React.MouseEvent, name: string) => {
    e.stopPropagation();
    if (!token || !confirm(`Delete project "${name}" permanently?`)) return;

    try {
      const response = await fetch(`/api/projects/${encodeURIComponent(name)}`, {
        method: 'DELETE',
        headers: { Authorization: `Bearer ${token}` }
      });

      if (response.ok) {
        await fetchProjects();
        await refreshProfile();
        addToast('Project deleted successfully', 'success');
      } else {
        const data = await response.json();
        addToast(data.error || 'Failed to delete project', 'error');
      }
    } catch (err) {
      addToast('Delete failed: ' + err, 'error');
    }
  };

  const handleExport = () => {
    const s = useBuilder.getState();
    downloadProject(s.projectName, Object.values(s.parts));
  };

  const handleImport = async (file: File) => {
    try {
      const proj = await importProjectFile(file);
      useBuilder.getState().loadParts(proj.parts, proj.name);
      addToast('Project imported successfully', 'success');
    } catch (err) {
      addToast(err instanceof Error ? err.message : 'Import failed', 'error');
    }
  };

  const handleNew = () => {
    if (confirm('Start a new empty project? Unsaved changes are kept in undo history.')) {
      useBuilder.getState().clearAll();
      setProjectName('Untitled system');
    }
  };

  const views: { id: ViewMode; label: string; title: string }[] = [
    { id: 'orbit', label: '3D', title: 'Free 3D orbit view' },
    { id: 'top', label: 'Top', title: 'Top-down plan view' },
    { id: 'front', label: 'Front', title: 'Front elevation view' },
    { id: 'side', label: 'Side', title: 'Side elevation view' },
  ];
  const renderModes: { id: RenderMode; label: string; title: string }[] = [
    { id: 'builder', label: 'Builder', title: 'Standard building mode' },
    { id: 'xray', label: 'X-Ray', title: 'Transparent shell with internal water visibility' },
    { id: 'water', label: 'Water', title: 'Water-first view with solids faded back' },
  ];

  return (
    <>
    <header className="flex h-12 shrink-0 items-center gap-2 border-b border-zinc-800 bg-zinc-950 px-3">
      <div className="flex items-center gap-2 pr-2">
        <span className="grid h-7 w-7 place-items-center rounded-lg bg-gradient-to-br from-sky-500 to-blue-700 text-sm font-black text-white">
          H
        </span>
        <input
          value={projectName}
          onChange={(e) => setProjectName(e.target.value)}
          className="w-44 rounded-md border border-transparent bg-transparent px-1.5 py-1 text-sm font-semibold text-zinc-100 outline-none hover:border-zinc-800 focus:border-sky-700 focus:bg-zinc-900"
        />
        <SaveIndicator />
      </div>

      <Divider />

      <TBtn onClick={handleNew} title="New empty project">New</TBtn>
      <TBtn onClick={handleSave} title="Save to cloud storage">Save</TBtn>
      <div className="relative">
        <TBtn onClick={() => setLoadOpen((o) => !o)} title="Load a saved project">
          Load ▾
        </TBtn>
        {loadOpen && (
          <div className="absolute top-9 left-0 z-50 max-h-72 w-64 overflow-y-auto rounded-lg border border-zinc-700 bg-zinc-900 p-1 shadow-2xl">
            {loadingProjects && (
              <div className="px-3 py-2 text-xs text-zinc-500">Loading...</div>
            )}
            {!loadingProjects && projectsList.length === 0 && (
              <div className="px-3 py-2 text-xs text-zinc-500">No saved projects yet.</div>
            )}
            {!loadingProjects && projectsList.map((p) => (
              <div
                key={p.name}
                className="flex items-center justify-between rounded-md px-3 py-1.5 hover:bg-zinc-800 group"
              >
                <button
                  onClick={() => handleLoad(p.name)}
                  className="flex-1 text-left text-xs text-zinc-200 outline-none"
                >
                  {p.name}
                  <span className="block text-[10px] text-zinc-500">
                    {new Date(p.savedAt).toLocaleString()}
                  </span>
                </button>
                <button
                  onClick={(e) => handleDelete(e, p.name)}
                  className="hidden group-hover:block text-[10px] text-red-400 hover:text-red-300 px-2 py-0.5 rounded bg-zinc-950/40"
                  title="Delete project"
                >
                  ✕
                </button>
              </div>
            ))}
            
            <div className="mt-2 border-t border-zinc-700/50 pt-2">
              <div className="px-3 pb-1 text-[10px] font-bold tracking-wider text-amber-500 uppercase">
                Premium Templates
              </div>
              {['Commercial DWC Layout', 'Basement Aeroponics Tower', 'NFT Lettuce Wall'].map((tName) => (
                <div key={tName} className="flex items-center justify-between rounded-md px-3 py-1.5 hover:bg-amber-950/30 group">
                  <button
                    onClick={() => {
                      if (!user || user.purchased_slots === 0) {
                        setShowPaywall(true);
                        setLoadOpen(false);
                      } else {
                        // Normally we would load the specific template JSON here.
                        // For the demo, we just reuse demoParts or clear the board.
                        addToast(`Loaded template: ${tName}`, 'success');
                        useBuilder.getState().clearAll();
                        setProjectName(tName);
                        setLoadOpen(false);
                      }
                    }}
                    className="flex-1 text-left text-xs text-amber-200/80 outline-none"
                  >
                    {tName} 🔒
                    <span className="block text-[10px] text-zinc-500">
                      Pro Template
                    </span>
                  </button>
                </div>
              ))}
            </div>
          </div>
        )}
      </div>
      <TBtn onClick={handleExport} title="Download design as JSON">Export</TBtn>
      <TBtn onClick={() => fileRef.current?.click()} title="Import a design JSON">Import</TBtn>
      <TBtn onClick={() => setShowShortcuts(true)} title="Show Keyboard Shortcuts">⌨️ Shortcuts</TBtn>
      <input
        ref={fileRef}
        type="file"
        accept="application/json,.json"
        className="hidden"
        onChange={(e) => {
          const f = e.target.files?.[0];
          if (f) void handleImport(f);
          e.target.value = '';
        }}
      />

      <Divider />

      <TBtn onClick={onOpenBom} title="Open bill of materials">BOM</TBtn>
      <TBtn onClick={onCheckBuild} title="Run design validation">Check Build</TBtn>
      <TBtn onClick={() => autoCapOpenEnds()} title="Add caps to every loose plumbing end">
        Auto Cap
      </TBtn>

      <Divider />

      <TBtn onClick={undo} disabled={!canUndo} title="Undo (⌘Z)">↶</TBtn>
      <TBtn onClick={redo} disabled={!canRedo} title="Redo (⇧⌘Z)">↷</TBtn>

      <Divider />

      <TBtn
        active={tool === 'measure'}
        onClick={() => setTool(tool === 'measure' ? 'select' : 'measure')}
        title="Measure: click two points in the scene"
      >
        📏 Measure
      </TBtn>
      <TBtn
        active={tool === 'pipeRun'}
        onClick={() => setTool(tool === 'pipeRun' ? 'select' : 'pipeRun')}
        title="Pipe Run: click two ground points"
      >
        Pipe Run
      </TBtn>
      <TBtn active={snapToGrid} onClick={toggleSnap} title="Snap to grid (0.25 ft)">
        ⌗ Snap
      </TBtn>

      <div className="ml-auto flex items-center gap-2">
        {/* Master play / pause for the water simulation */}
        <button
          onClick={toggleSimRunning}
          title={simRunning ? 'Pause water simulation (Space)' : 'Run water simulation (Space)'}
          className={`grid h-8 w-8 shrink-0 place-items-center rounded-full text-white shadow-lg transition-all hover:scale-110 active:scale-95 ${
            simRunning
              ? 'bg-emerald-500 shadow-emerald-500/40 hover:bg-emerald-400'
              : 'bg-sky-600 shadow-sky-600/40 hover:bg-sky-500'
          }`}
        >
          {simRunning ? (
            <svg viewBox="0 0 16 16" className="h-3.5 w-3.5" fill="currentColor">
              <rect x="3" y="2.5" width="3.4" height="11" rx="1" />
              <rect x="9.6" y="2.5" width="3.4" height="11" rx="1" />
            </svg>
          ) : (
            <svg viewBox="0 0 16 16" className="ml-0.5 h-3.5 w-3.5" fill="currentColor">
              <path d="M4 2.8a1 1 0 0 1 1.52-.86l8.2 5.2a1 1 0 0 1 0 1.7l-8.2 5.2A1 1 0 0 1 4 13.2V2.8Z" />
            </svg>
          )}
        </button>
        <div className="flex items-center gap-1.5 bg-zinc-900 border border-zinc-800 rounded-lg px-2.5 py-1">
          <span className="text-[10px] uppercase font-bold text-zinc-400">Stage</span>
          <select
            value={growthStage}
            onChange={(e) => setGrowthStage(e.target.value as any)}
            className="bg-transparent text-xs text-zinc-200 outline-none border-none cursor-pointer pr-1"
          >
            <option value="seedling" className="bg-zinc-900 text-zinc-200">Seedling</option>
            <option value="vegetative" className="bg-zinc-900 text-zinc-200">Vegetative</option>
            <option value="flowering" className="bg-zinc-900 text-zinc-200">Flowering</option>
          </select>
        </div>
        <TBtn active={showFlow} onClick={toggleFlow} title="Toggle water flow animation">
          💧 Flow
        </TBtn>
        <div className="flex overflow-hidden rounded-lg border border-zinc-800">
          {renderModes.map((mode) => (
            <button
              key={mode.id}
              onClick={() => setRenderMode(mode.id)}
              title={mode.title}
              className={`px-3 py-1.5 text-xs font-medium transition ${
                renderMode === mode.id
                  ? 'bg-cyan-600 text-white'
                  : 'bg-zinc-900 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200'
              }`}
            >
              {mode.label}
            </button>
          ))}
        </div>
        <div className="flex overflow-hidden rounded-lg border border-zinc-800">
          {views.map((v) => (
            <button
              key={v.id}
              onClick={() => setViewMode(v.id)}
              title={v.title}
              className={`px-3 py-1.5 text-xs font-medium transition ${
                viewMode === v.id
                  ? 'bg-sky-600 text-white'
                  : 'bg-zinc-900 text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200'
              }`}
            >
              {v.label}
            </button>
          ))}
        </div>

        {user && (
          <>
            <Divider />
            <div className="flex items-center gap-2 px-1">
              <div className="flex flex-col items-end">
                <span className="text-[10px] font-semibold text-zinc-300 max-w-24 truncate">
                  {user.email}
                </span>
                <span className={`text-[9px] font-bold uppercase ${user.total_slots === 0 ? 'text-amber-400' : user.project_count >= user.total_slots ? 'text-amber-400' : 'text-emerald-400'}`}>
                  {user.project_count} / {user.total_slots} Slots
                </span>
              </div>
              
              {user.total_slots === 0 ? (
                <button
                  onClick={() => setShowPaywall(true)}
                  className="rounded bg-gradient-to-r from-sky-500/20 to-blue-500/20 hover:from-sky-500/30 hover:to-blue-500/30 text-sky-300 border border-sky-700 px-2 py-1 text-[10px] font-bold transition cursor-pointer flex items-center gap-1 shadow-lg"
                >
                  💎 Upgrade
                </button>
              ) : (
                user.project_count >= user.total_slots && (
                  <button
                    onClick={() => setShowPaywall(true)}
                    className="rounded bg-amber-500/20 hover:bg-amber-500/30 text-amber-300 border border-amber-600/30 px-2 py-1 text-[10px] font-semibold transition cursor-pointer"
                  >
                    + Add Slot
                  </button>
                )
              )}
              
              <button
                onClick={logout}
                className="rounded border border-zinc-800 bg-zinc-900 px-2 py-1 text-[10px] font-medium text-zinc-400 hover:bg-zinc-800 hover:text-zinc-200 transition cursor-pointer"
              >
                Logout
              </button>
            </div>
          </>
        )}
      </div>

      {showPaywall && <PaywallModal onClose={() => setShowPaywall(false)} />}
      
      {showShortcuts && (
        <div className="fixed inset-0 z-[120] flex items-center justify-center bg-zinc-950/80 backdrop-blur-sm">
          <div className="w-full max-w-sm rounded-xl border border-zinc-800 bg-zinc-900 p-6 shadow-2xl text-left">
            <h3 className="text-sm font-bold text-zinc-100 mb-4 flex items-center gap-1.5 border-b border-zinc-800 pb-2">
              ⌨️ Keyboard Shortcuts
            </h3>
            <div className="space-y-2.5 text-xs text-zinc-400">
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Undo / Redo</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">⌘Z / ⌘Y</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Rotate Selected</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">R</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Duplicate Selected</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">D</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Delete Selected</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">⌫ / Del</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Run / Pause Sim</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">Spacebar</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Pan Camera View</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">Arrow Keys</span>
              </div>
              <div className="flex justify-between border-b border-zinc-800/40 pb-1.5">
                <span>Clear Selection & Tool</span>
                <span className="font-mono bg-zinc-950 px-1.5 py-0.5 rounded text-zinc-300">Esc</span>
              </div>
            </div>
            <button
              onClick={() => setShowShortcuts(false)}
              className="mt-6 w-full rounded bg-zinc-800 py-2 text-xs font-semibold text-zinc-200 hover:bg-zinc-700 transition cursor-pointer"
            >
              Close
            </button>
          </div>
        </div>
      )}
    </header>

    {/* Tabbed room bar */}
    <div className="flex h-10 shrink-0 items-center justify-between border-b border-zinc-850 bg-zinc-900/60 px-3">
      <div className="flex items-center gap-1.5 overflow-x-auto">
        {rooms.map((room) => {
          const isActive = room.id === activeRoomId;
          return (
            <div
              key={room.id}
              className={`group flex items-center gap-1.5 rounded-md px-2.5 py-1 text-xs font-semibold transition cursor-pointer select-none ${
                isActive
                  ? 'bg-sky-500/15 text-sky-400 border border-sky-500/30'
                  : 'text-zinc-400 hover:text-zinc-200 border border-transparent'
              }`}
              onClick={() => setActiveRoomId(room.id)}
            >
              <span>{room.name}</span>
              {rooms.length > 1 && (
                <button
                  onClick={(e) => {
                    e.stopPropagation();
                    if (confirm(`Delete room "${room.name}" and all its parts permanently?`)) {
                      removeRoom(room.id);
                    }
                  }}
                  className="opacity-0 group-hover:opacity-100 hover:text-red-400 text-[10px] ml-1 transition"
                >
                  ✕
                </button>
              )}
            </div>
          );
        })}
      </div>
      <button
        onClick={() => {
          const name = prompt('Enter room name:', `Room ${rooms.length + 1}`);
          if (name) {
            addRoom(name.trim());
          }
        }}
        className="rounded border border-zinc-700 bg-zinc-850 hover:bg-zinc-800 text-zinc-300 px-2.5 py-1 text-[11px] font-semibold transition flex items-center gap-1 cursor-pointer"
      >
        + Add Room
      </button>
    </div>
    </>
  );
}

function Divider() {
  return <div className="mx-1 h-6 w-px bg-zinc-800" />;
}

function TBtn({
  children,
  onClick,
  title,
  active,
  disabled,
}: {
  children: React.ReactNode;
  onClick: () => void;
  title?: string;
  active?: boolean;
  disabled?: boolean;
}) {
  return (
    <button
      onClick={onClick}
      title={title}
      disabled={disabled}
      className={`rounded-md px-2.5 py-1.5 text-xs font-medium transition disabled:cursor-default disabled:opacity-30
        ${
          active
            ? 'bg-sky-500/15 text-sky-300 ring-1 ring-sky-700'
            : 'text-zinc-300 hover:bg-zinc-800'
        }`}
    >
      {children}
    </button>
  );
}
