import { useEffect, useState, useMemo, useCallback, useRef } from 'react';
import { useEditorStore } from './store/editorStore';
import VideoPlayer from './components/VideoPlayer';
import TranscriptEditor from './components/TranscriptEditor';
import WaveformTimeline from './components/WaveformTimeline';
import AIPanel from './components/AIPanel';
import ExportDialog from './components/ExportDialog';
import SettingsPanel from './components/SettingsPanel';
import DevPanel from './components/DevPanel';
import MarkersPanel from './components/MarkersPanel';
import SilenceTrimmerPanel from './components/SilenceTrimmerPanel';
import ZoneEditor from './components/ZoneEditor';
import BackgroundMusicPanel from './components/BackgroundMusicPanel';
import AppendClipPanel from './components/AppendClipPanel';
import LicenseDialog from './components/LicenseDialog';
import HelpContent from './components/HelpContent';
import { useKeyboardShortcuts } from './hooks/useKeyboardShortcuts';
import { useLicenseStore } from './store/licenseStore';
import {
  Film,
  FolderOpen,
  Settings,
  Sparkles,
  Download,
  FileInput,
  Save,
  Scissors,
  VolumeX,
  SlidersHorizontal,
  Gauge,
  FilePlus2,
  RefreshCw,
  Grid3x3,
  MapPin,
  Music,
  ListVideo,
  Clock,
  AlertTriangle,
  HelpCircle,
} from 'lucide-react';

const LAST_MEDIA_PATH_KEY = 'talkedit:lastMediaPath';

type Panel = 'ai' | 'settings' | 'export' | 'silence' | 'zones' | 'markers' | 'music' | 'append' | 'help' | null;

export default function App() {
    const {
      projectFilePath,
      videoPath,
      exportedAudioPath,
      words,
      segments,
      cutRanges,
      muteRanges,
      gainRanges,
      speedRanges,
      globalGainDb,
      silenceTrimGroups,
      transcriptionModel,
      language,
      isTranscribing,
      transcriptionStatus,
      markInTime,
      markOutTime,
      loadVideo,
      setProjectFilePath,
      setBackendUrl,
      clearMarkRange,
      setTranscription,
      setTranscriptionModel,
      setTranscribing,
      selectedWordIndices,
      addCutRange,
      addMuteRange,
      addGainRange,
      addSpeedRange,
      backendUrl,
    } = useEditorStore();

  const [activePanel, setActivePanel] = useState<Panel>(null);
  const [projectName, setProjectName] = useState<string | null>(null);
  const [splitRatio, setSplitRatio] = useState(() => {
    try { return Number(localStorage.getItem('talkedit:splitRatio')) || 0.5; } catch { return 0.5; }
  });
  const splitRef = useRef<HTMLDivElement>(null);
  const isDraggingSplit = useRef(false);

  const startSplitDrag = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    isDraggingSplit.current = true;
    const container = splitRef.current?.parentElement;
    if (!container) return;
    const rect = container.getBoundingClientRect();
    const onMove = (me: MouseEvent) => {
      if (!isDraggingSplit.current) return;
      const pct = (me.clientX - rect.left) / rect.width;
      const clamped = Math.max(0.15, Math.min(0.85, pct));
      setSplitRatio(clamped);
      localStorage.setItem('talkedit:splitRatio', String(clamped));
    };
    const onUp = () => { isDraggingSplit.current = false; window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
  }, []);

  // Draggable right sidebar
  const [sidebarWidth, setSidebarWidth] = useState(() => {
    try { return Number(localStorage.getItem('talkedit:sidebarWidth')) || 320; } catch { return 320; }
  });
  const isDraggingSidebar = useRef(false);

  const startSidebarDrag = useCallback((e: React.MouseEvent) => {
    e.preventDefault();
    isDraggingSidebar.current = true;
    const container = document.querySelector('.main-content') as HTMLElement;
    if (!container) return;
    const rect = container.getBoundingClientRect();
    const onMove = (me: MouseEvent) => {
      if (!isDraggingSidebar.current) return;
      const w = rect.right - me.clientX;
      const clamped = Math.max(180, Math.min(600, w));
      setSidebarWidth(clamped);
      localStorage.setItem('talkedit:sidebarWidth', String(clamped));
    };
    const onUp = () => { isDraggingSidebar.current = false; window.removeEventListener('mousemove', onMove); window.removeEventListener('mouseup', onUp); };
    window.addEventListener('mousemove', onMove);
    window.addEventListener('mouseup', onUp);
  }, []);

  const [whisperModel, setWhisperModel] = useState('base');
  useEffect(() => { if (transcriptionModel) setWhisperModel(transcriptionModel); }, [transcriptionModel]);
  const [cutMode, setCutMode] = useState(false);
  const [muteMode, setMuteMode] = useState(false);
  const [gainMode, setGainMode] = useState(false);
  const [gainModeDb, setGainModeDb] = useState(3);
  const [speedMode, setSpeedMode] = useState(false);
  const [speedModeValue, setSpeedModeValue] = useState(1.25);
  const [showReprocessConfirm, setShowReprocessConfirm] = useState(false);
  const [showWelcomeOverlay, setShowWelcomeOverlay] = useState(() => {
    return localStorage.getItem('talkedit:welcomeDismissed') !== 'true';
  });
  const [showUnsavedPrompt, setShowUnsavedPrompt] = useState(false);
  const [pendingProceedAction, setPendingProceedAction] = useState<(() => Promise<void>) | null>(null);
  const [lastSavedSignature, setLastSavedSignature] = useState<string | null>(null);
  const [showFileMenu, setShowFileMenu] = useState(false);
  const [showRecoveryDialog, setShowRecoveryDialog] = useState(false);
  const [recoveryData, setRecoveryData] = useState<any>(null);
  const [recoveryMinutesAgo, setRecoveryMinutesAgo] = useState(0);
  const [backendDown, setBackendDown] = useState(false);
  const canEdit = useLicenseStore((s) => s.canEdit);
  const licenseStatus = useLicenseStore((s) => s.status);
  const setShowLicenseDialog = useLicenseStore((s) => s.setShowDialog);

  const projectSignature = useMemo(() => {
    if (!videoPath) return null;
    return JSON.stringify({
      videoPath,
      exportedAudioPath,
      words,
      segments,
      cutRanges,
      muteRanges,
      gainRanges,
      speedRanges,
      globalGainDb,
      silenceTrimGroups,
      transcriptionModel,
      language,
    });
  }, [
    videoPath,
    exportedAudioPath,
    words,
    segments,
    cutRanges,
    muteRanges,
    gainRanges,
    speedRanges,
    globalGainDb,
    silenceTrimGroups,
    transcriptionModel,
    language,
  ]);

  const hasUnsavedChanges = Boolean(projectSignature) && projectSignature !== lastSavedSignature;

  const loadProjectFromData = (data: any) => {
    const removedCount = useEditorStore.getState().loadProject(data);
    if (removedCount > 0) {
      window.alert(`${removedCount} invalid zones were removed from the loaded project.`);
    }
    const loadedSignature = JSON.stringify({
      videoPath: data.videoPath,
      exportedAudioPath: data.exportedAudioPath ?? null,
      words: data.words || [],
      segments: data.segments || [],
      cutRanges: [...(data.cutRanges || []), ...(data.deletedRanges || []).map((r: any) => ({ id: r.id, start: r.start, end: r.end }))],
      muteRanges: data.muteRanges || [],
      gainRanges: data.gainRanges || [],
      speedRanges: data.speedRanges || [],
      globalGainDb: typeof data.globalGainDb === 'number' ? data.globalGainDb : 0,
      silenceTrimGroups: data.silenceTrimGroups || [],
      transcriptionModel: data.transcriptionModel ?? null,
      language: data.language || '',
    });
    setLastSavedSignature(loadedSignature);
  };

  const runGuarded = async (action: () => Promise<void>) => {
    if (!hasUnsavedChanges) {
      await action();
      return;
    }
    setPendingProceedAction(() => action);
    setShowUnsavedPrompt(true);
  };

  useKeyboardShortcuts();

  useEffect(() => {
    useLicenseStore.getState().checkStatus();
    window.electronAPI?.readAutosave().then((data) => {
      if (data) {
        try {
          const parsed = JSON.parse(data);
          const savedAt = parsed.savedAt;
          const minutesAgo = savedAt ? Math.round((Date.now() - savedAt) / 60000) : 0;
          setRecoveryData(parsed);
          setRecoveryMinutesAgo(minutesAgo);
          setShowRecoveryDialog(true);
        } catch {}
      }
    });
  }, []);

  // Handle Escape key to exit timeline zone modes and close menus
  useEffect(() => {
    const handleKeyDown = (e: KeyboardEvent) => {
      if (e.key === 'Escape') {
        setCutMode(false);
        setMuteMode(false);
        setGainMode(false);
        setSpeedMode(false);
        setShowFileMenu(false);
      }
    };
    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, []);

  useEffect(() => {
    window.electronAPI!.getBackendUrl().then(setBackendUrl);
  }, [setBackendUrl]);

  useEffect(() => {
    if (videoPath) return;
    const savedPath = sessionStorage.getItem(LAST_MEDIA_PATH_KEY);
    if (savedPath) {
      loadVideo(savedPath);
    }
  }, [videoPath, loadVideo]);

  useEffect(() => {
    if (videoPath) {
      sessionStorage.setItem(LAST_MEDIA_PATH_KEY, videoPath);
      return;
    }
    sessionStorage.removeItem(LAST_MEDIA_PATH_KEY);
  }, [videoPath]);

  useEffect(() => {
    if (!videoPath) return;

    const interval = setInterval(() => {
      const state = useEditorStore.getState();
      const hasData = state.words.length > 0 || state.cutRanges.length > 0 || state.muteRanges.length > 0 || state.gainRanges.length > 0 || state.speedRanges.length > 0;
      if (!hasData) return;
      const autosaveData = {
        savedAt: Date.now(),
        videoPath: state.videoPath,
        words: state.words,
        segments: state.segments,
        cutRanges: state.cutRanges,
        muteRanges: state.muteRanges,
        gainRanges: state.gainRanges,
        speedRanges: state.speedRanges,
        globalGainDb: state.globalGainDb,
        silenceTrimGroups: state.silenceTrimGroups,
        transcriptionModel: state.transcriptionModel,
        language: state.language,
        markInTime: state.markInTime,
        markOutTime: state.markOutTime,
        timelineMarkers: state.timelineMarkers,
      };
      window.electronAPI.writeAutosave(JSON.stringify(autosaveData));
    }, 60000);

    return () => clearInterval(interval);
  }, [videoPath]);

  const handleLoadProject = async () => {
    await runGuarded(async () => {
      try {
        const projectPath = await window.electronAPI!.openProject();
        if (!projectPath) return;
        const content = await window.electronAPI!.readFile(projectPath);
        const data = JSON.parse(content);
        setProjectFilePath(projectPath);
        loadProjectFromData(data);
        setProjectName(projectPath.split(/[/\\]/).pop()?.replace(/\.aive$/i, '') ?? null);
      } catch (err) {
        console.error('Failed to load project:', err);
        alert(`Failed to load project: ${err}`);
      }
    });
  };

  const writeProjectToPath = async (path: string): Promise<boolean> => {
    try {
      const data = useEditorStore.getState().saveProject();
      const resolvedPath = path.endsWith('.aive') ? path : `${path}.aive`;
      await window.electronAPI!.writeFile(resolvedPath, JSON.stringify(data, null, 2));
      setProjectFilePath(resolvedPath);
      setProjectName(resolvedPath.split(/[/\\]/).pop()?.replace(/\.aive$/i, '') ?? null);
      if (projectSignature) {
        setLastSavedSignature(projectSignature);
      }
      return true;
    } catch (err) {
      console.error('Failed to save project:', err);
      alert(`Failed to save project: ${err}`);
      return false;
    }
  };

  const handleSaveProjectAs = async (): Promise<boolean> => {
    const savePath = await window.electronAPI!.saveProject();
    if (!savePath) return false;
    return writeProjectToPath(savePath);
  };

  const handleSaveProject = async (): Promise<boolean> => {
    if (!projectFilePath) {
      return handleSaveProjectAs();
    }
    return writeProjectToPath(projectFilePath);
  };

  const handleOpenFile = async () => {
    await runGuarded(async () => {
      const path = await window.electronAPI!.openFile();
      if (path) {
        setLastSavedSignature(null);
        setProjectFilePath(null);
        setProjectName(null);
        loadVideo(path);
        if (canEdit) {
          await transcribeVideo(path);
        }
      }
    });
  };

  const handleNewProject = () => {
    runGuarded(async () => {
      useEditorStore.getState().reset();
      setLastSavedSignature(null);
      setActivePanel(null);
      setProjectFilePath(null);
      setProjectName(null);
      setCutMode(false);
      setMuteMode(false);
      setGainMode(false);
      setSpeedMode(false);
    });
  };

  const transcribeVideo = async (path: string) => {
    setTranscribing(true, 0, 'Checking model...');
    try {
      // Step 1: ensure model is downloaded (may take a while on first run)
      const MODEL_SIZES: Record<string, string> = {
        'tiny':              '~75 MB',
        'tiny.en':           '~75 MB',
        'base':              '~140 MB',
        'base.en':           '~140 MB',
        'small':             '~460 MB',
        'small.en':          '~460 MB',
        'medium':            '~1.5 GB',
        'medium.en':         '~1.5 GB',
        'large':             '~2.9 GB',
        'large-v2':          '~2.9 GB',
        'large-v3':          '~2.9 GB',
        'large-v3-turbo':    '~1.6 GB',
        'distil-large-v3':   '~1.5 GB',
        'distil-medium.en':  '~750 MB',
        'distil-small.en':   '~190 MB',
      };
      const modelLabel = MODEL_SIZES[whisperModel] ?? 'unknown size';
      setTranscribing(true, 5, `Downloading ${whisperModel} model (${modelLabel})...`);
      await window.electronAPI.ensureModel(whisperModel);

      // Step 2: run transcription
      setTranscribing(true, 20, 'Transcribing audio...');
      const data = await window.electronAPI.transcribe(path, whisperModel);
      setTranscription(data);
      setTranscriptionModel(whisperModel);
    } catch (err) {
      console.error('Transcription error:', err);
      alert(`Transcription failed. Check the console for details.\n\n${err}`);
    } finally {
      setTranscribing(false);
    }
  };

  const handleReprocessProject = async () => {
    if (!videoPath) return;

    await runGuarded(async () => {
      setShowReprocessConfirm(true);
    });
  };

  const confirmReprocessProject = async () => {
    if (!videoPath) return;
    setShowReprocessConfirm(false);
    await transcribeVideo(videoPath);
  };

  const handleUnsavedSaveAndContinue = async () => {
    const action = pendingProceedAction;
    if (!action) {
      setShowUnsavedPrompt(false);
      return;
    }
    const didSave = await handleSaveProject();
    if (!didSave) return;
    setShowUnsavedPrompt(false);
    setPendingProceedAction(null);
    await action();
  };

  const handleUnsavedDiscardAndContinue = async () => {
    const action = pendingProceedAction;
    setShowUnsavedPrompt(false);
    setPendingProceedAction(null);
    if (action) {
      await action();
    }
  };

  const handleUnsavedCancel = () => {
    setShowUnsavedPrompt(false);
    setPendingProceedAction(null);
  };

  const handleRecoverAutosave = () => {
    if (!recoveryData) return;
    const data = recoveryData;
    const removedCount = useEditorStore.getState().loadProject(data);
    if (removedCount > 0) {
      window.alert(`${removedCount} invalid zones were removed from the loaded project.`);
    }
    if (data.markInTime != null) useEditorStore.getState().setMarkInTime(data.markInTime);
    if (data.markOutTime != null) useEditorStore.getState().setMarkOutTime(data.markOutTime);
    window.electronAPI.deleteAutosave();
    setShowRecoveryDialog(false);
    setRecoveryData(null);
  };

  const handleDismissRecovery = () => {
    window.electronAPI.deleteAutosave();
    setShowRecoveryDialog(false);
    setRecoveryData(null);
  };

  const togglePanel = (panel: Panel) => {
    setActivePanel((prev) => (prev === panel ? null : panel));
  };

  const handleCut = () => {
    if (markInTime !== null && markOutTime !== null) {
      const startTime = Math.min(markInTime, markOutTime);
      const endTime = Math.max(markInTime, markOutTime);
      if (endTime - startTime >= 0.01) {
        addCutRange(startTime, endTime);
        setActivePanel('zones');
      }
      clearMarkRange();
      return;
    }

    if (selectedWordIndices.length > 0) {
      // If words are selected, apply cut immediately
      const sorted = [...selectedWordIndices].sort((a, b) => a - b);
      const startTime = words[sorted[0]].start;
      const endTime = words[sorted[sorted.length - 1]].end;
      addCutRange(startTime, endTime);
    } else {
      // Toggle cut mode
      setCutMode(!cutMode);
      setMuteMode(false); // Exit mute mode
      setGainMode(false); // Exit gain mode
      setSpeedMode(false); // Exit speed mode
    }
  };

  const handleMute = () => {
    if (markInTime !== null && markOutTime !== null) {
      const startTime = Math.min(markInTime, markOutTime);
      const endTime = Math.max(markInTime, markOutTime);
      if (endTime - startTime >= 0.01) {
        addMuteRange(startTime, endTime);
        setActivePanel('zones');
      }
      clearMarkRange();
      return;
    }

    if (selectedWordIndices.length > 0) {
      // If words are selected, apply mute immediately
      const sorted = [...selectedWordIndices].sort((a, b) => a - b);
      const startTime = words[sorted[0]].start;
      const endTime = words[sorted[sorted.length - 1]].end;
      addMuteRange(startTime, endTime);
    } else {
      // Toggle mute mode
      setMuteMode(!muteMode);
      setCutMode(false); // Exit cut mode
      setGainMode(false); // Exit gain mode
      setSpeedMode(false); // Exit speed mode
    }
  };

  const handleGain = () => {
    if (markInTime !== null && markOutTime !== null) {
      const startTime = Math.min(markInTime, markOutTime);
      const endTime = Math.max(markInTime, markOutTime);
      if (endTime - startTime >= 0.01) {
        addGainRange(startTime, endTime, gainModeDb);
        setActivePanel('zones');
      }
      clearMarkRange();
      return;
    }

    if (selectedWordIndices.length > 0) {
      const sorted = [...selectedWordIndices].sort((a, b) => a - b);
      const startTime = words[sorted[0]].start;
      const endTime = words[sorted[sorted.length - 1]].end;
      addGainRange(startTime, endTime, gainModeDb);
    } else {
      setGainMode(!gainMode);
      setCutMode(false);
      setMuteMode(false);
      setSpeedMode(false);
    }
  };

  const handleSpeed = () => {
    if (markInTime !== null && markOutTime !== null) {
      const startTime = Math.min(markInTime, markOutTime);
      const endTime = Math.max(markInTime, markOutTime);
      if (endTime - startTime >= 0.01) {
        addSpeedRange(startTime, endTime, speedModeValue);
        setActivePanel('zones');
      }
      clearMarkRange();
      return;
    }

    if (selectedWordIndices.length > 0) {
      const sorted = [...selectedWordIndices].sort((a, b) => a - b);
      const startTime = words[sorted[0]].start;
      const endTime = words[sorted[sorted.length - 1]].end;
      addSpeedRange(startTime, endTime, speedModeValue);
    } else {
      setSpeedMode(!speedMode);
      setCutMode(false);
      setMuteMode(false);
      setGainMode(false);
    }
  };

  if (!videoPath) {
    return (
      <div className="h-screen flex flex-col bg-editor-bg relative overflow-hidden">
        {/* Background pattern */}
        <div className="absolute inset-0 opacity-[0.03] pointer-events-none" style={{
          backgroundImage: `radial-gradient(circle at 25% 25%, #6366f1 1px, transparent 1px),
            radial-gradient(circle at 75% 75%, #818cf8 1px, transparent 1px)`,
          backgroundSize: '60px 60px, 80px 80px',
        }} />

        {/* Animated audio waveform background — left and right sides filling to center */}
        <div className="absolute inset-y-0 left-0 w-[30%] flex items-center justify-end gap-[3px] pr-16 pointer-events-none opacity-[0.09]">
          {[
            [60, 1.3, 0.0], [100, 1.0, 0.12], [40, 1.6, 0.24], [120, 0.9, 0.08],
            [80, 1.2, 0.2], [30, 1.8, 0.04], [110, 1.1, 0.28], [50, 1.5, 0.16],
            [70, 1.4, 0.08], [140, 0.85, 0.24], [60, 1.3, 0.12], [90, 1.2, 0.0],
            [130, 0.95, 0.2], [45, 1.7, 0.28], [80, 1.4, 0.04], [55, 1.1, 0.16],
            [100, 1.3, 0.24], [35, 1.6, 0.12], [120, 0.9, 0.0], [65, 1.5, 0.2],
            [85, 1.2, 0.08], [150, 0.8, 0.28], [40, 1.9, 0.16], [95, 1.1, 0.04],
            [75, 1.4, 0.24], [25, 2.0, 0.12], [105, 1.05, 0.2], [155, 0.82, 0.08],
            [50, 1.55, 0.28], [115, 0.92, 0.16], [70, 1.35, 0.04], [135, 0.88, 0.24],
            [90, 1.15, 0.12], [42, 1.75, 0.0], [125, 0.98, 0.2], [58, 1.45, 0.08],
          ].map(([peak, dur, delay], i) => (
            <div
              key={`left-${i}`}
              className="welcome-audio-bar"
              style={{
                '--bar-peak': `${peak}px`,
                '--bar-duration': `${dur}s`,
                '--bar-delay': `${delay}s`,
              } as React.CSSProperties}
            />
          ))}
        </div>
        <div className="absolute inset-y-0 right-0 w-[30%] flex items-center justify-start gap-[3px] pl-16 pointer-events-none opacity-[0.09]">
          {[
            [100, 1.0, 0.0], [60, 1.3, 0.08], [130, 0.9, 0.16], [40, 1.6, 0.04],
            [80, 1.2, 0.12], [150, 0.85, 0.24], [50, 1.5, 0.2], [110, 1.1, 0.28],
            [70, 1.4, 0.08], [30, 1.8, 0.16], [140, 0.9, 0.0], [90, 1.2, 0.24],
            [60, 1.3, 0.12], [120, 0.95, 0.04], [85, 1.4, 0.2], [45, 1.7, 0.28],
            [160, 0.8, 0.08], [55, 1.5, 0.24], [100, 1.1, 0.0], [75, 1.3, 0.16],
            [35, 1.9, 0.2], [115, 1.0, 0.12], [65, 1.6, 0.28], [140, 0.88, 0.04],
            [95, 1.25, 0.24], [25, 1.85, 0.08], [125, 0.93, 0.16], [155, 0.78, 0.28],
            [48, 1.65, 0.12], [82, 1.32, 0.2], [108, 1.08, 0.04], [72, 1.42, 0.24],
            [135, 0.9, 0.16], [38, 1.78, 0.0], [62, 1.48, 0.08], [118, 1.02, 0.28],
          ].map(([peak, dur, delay], i) => (
            <div
              key={`right-${i}`}
              className="welcome-audio-bar"
              style={{
                '--bar-peak': `${peak}px`,
                '--bar-duration': `${dur}s`,
                '--bar-delay': `${delay}s`,
              } as React.CSSProperties}
            />
          ))}
        </div>

        <div className="absolute top-1/4 -left-32 w-96 h-96 bg-editor-accent/5 rounded-full blur-3xl pointer-events-none" />
        <div className="absolute bottom-1/4 -right-32 w-96 h-96 bg-blue-500/5 rounded-full blur-3xl pointer-events-none" />

        <div className="flex-1 flex flex-col items-center justify-center gap-6 px-6 relative z-10">
          {/* App icon */}
          <div className="w-36 h-36 rounded-[20px] bg-editor-accent/10 border border-editor-accent/20 flex items-center justify-center shadow-lg shadow-editor-accent/10">
            <svg width="96" height="96" viewBox="0 0 36 36" fill="none" xmlns="http://www.w3.org/2000/svg">
              <path d="M6 10h12a6 6 0 0 1 0 12H8l-2 4V10Z" stroke="#818cf8" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" opacity="0.7"/>
              <path d="M6 10h12a6 6 0 0 1 0 12H8l-2 4V10Z" stroke="#6366f1" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
              <path d="M10 14v4M13 13v6M16 14v4" stroke="#6366f1" strokeWidth="1.5" strokeLinecap="round"/>
              <path d="M22 16h6M22 19h4M22 22h5" stroke="#818cf8" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" opacity="0.6"/>
            </svg>
          </div>

          <div className="flex flex-col items-center gap-2">
            <h1 className="text-3xl font-bold tracking-tight text-editor-text">
              Talk<span className="text-editor-accent">Edit</span>
            </h1>
            <p className="text-editor-text-muted text-sm max-w-sm text-center leading-relaxed">
              The offline video editor that doesn't slow down on long files.
            </p>
          </div>

          {/* Action row — button + model selector side by side */}
          <div className="flex items-center gap-3 mt-2">
            <button
              onClick={handleOpenFile}
              className="flex items-center gap-2 px-8 py-3 bg-editor-accent hover:bg-editor-accent-hover rounded-xl text-white font-medium transition-all hover:scale-[1.02] active:scale-[0.98]"
            >
              <FolderOpen className="w-5 h-5" />
              Process File
            </button>
            <div className="flex items-center gap-2 px-4 py-2.5 rounded-xl bg-editor-surface/50 border border-editor-border/50">
              <span className="text-xs text-editor-text-muted whitespace-nowrap">Transcription model:</span>
              <select
                value={whisperModel}
                onChange={(e) => setWhisperModel(e.target.value)}
                className="bg-transparent text-xs text-editor-text focus:outline-none [color-scheme:dark]"
                title="Choose Whisper model for transcription accuracy"
              >
                <optgroup label="Multilingual">
                  <option value="tiny">tiny (75 MB · fastest)</option>
                  <option value="base">base (140 MB · fast)</option>
                  <option value="small">small (460 MB · balanced)</option>
                  <option value="medium">medium (1.5 GB · better)</option>
                  <option value="large-v3-turbo">large-v3-turbo (1.6 GB ★)</option>
                  <option value="large-v3">large-v3 (2.9 GB · best)</option>
                </optgroup>
                <optgroup label="English-only (faster)">
                  <option value="tiny.en">tiny.en (75 MB)</option>
                  <option value="base.en">base.en (140 MB)</option>
                  <option value="small.en">small.en (460 MB)</option>
                  <option value="medium.en">medium.en (1.5 GB)</option>
                  <option value="distil-small.en">distil-small.en (190 MB ★)</option>
                  <option value="distil-medium.en">distil-medium.en (750 MB ★)</option>
                </optgroup>
              </select>
            </div>
          </div>

          <button
            onClick={handleLoadProject}
            className="flex items-center gap-2 px-4 py-2 text-sm text-editor-text-muted hover:text-editor-text hover:bg-editor-surface rounded-lg transition-colors"
          >
            <FileInput className="w-4 h-4" />
            Load Project (.aive)
          </button>
        </div>

        {licenseStatus?.tag === 'Trial' && (
          <div className="h-9 flex items-center justify-center gap-2 px-4 bg-editor-accent/10 border-t border-editor-accent/20 shrink-0 relative z-10">
            <Clock className="w-3.5 h-3.5 text-editor-accent shrink-0" />
            <span className="text-xs text-editor-accent">
              Free trial: {licenseStatus.days_remaining} day{licenseStatus.days_remaining !== 1 ? 's' : ''} remaining
            </span>
            <button
              onClick={() => setShowLicenseDialog(true)}
              className="text-xs text-editor-accent underline font-medium hover:text-editor-accent-hover ml-2"
            >
              Activate license
            </button>
          </div>
        )}

        {licenseStatus?.tag === 'Expired' && (
          <div className="h-9 flex items-center justify-center gap-2 px-4 bg-red-500/15 border-t border-red-500/30 shrink-0 relative z-10">
            <AlertTriangle className="w-3.5 h-3.5 text-red-400 shrink-0" />
            <span className="text-xs text-red-300">Trial expired</span>
            <button
              onClick={() => setShowLicenseDialog(true)}
              className="text-xs text-red-300 underline font-medium hover:text-red-200 ml-2"
            >
              Activate license
            </button>
          </div>
        )}
      </div>
    );
  }

  // Health check timer
  useEffect(() => {
    const checkHealth = async () => {
      try {
        const res = await fetch(`${backendUrl}/health`);
        setBackendDown(!res.ok);
      } catch {
        setBackendDown(true);
      }
    };
    checkHealth();
    const interval = setInterval(checkHealth, 30000);
    return () => clearInterval(interval);
  }, [videoPath, backendUrl]);

  return (
    <div className="h-screen flex flex-col bg-editor-bg overflow-hidden">
      {/* Top bar */}
      <header className="h-12 flex items-center px-4 border-b border-editor-border shrink-0">
        <div className="flex items-center gap-0.5">
          <div className="relative">
            <ToolbarButton
              icon={<FolderOpen className="w-4 h-4" />}
              label="File"
              onClick={() => setShowFileMenu((p) => !p)}
              active={showFileMenu}
            />
            {showFileMenu && (
              <>
                <div className="fixed inset-0 z-40" onClick={() => setShowFileMenu(false)} />
                <div className="absolute left-0 top-full mt-1 z-50 w-44 rounded-lg border border-editor-border bg-editor-surface shadow-xl py-1">
                  <DropdownItem icon={<FilePlus2 className="w-4 h-4" />} label="New Project" title="Start a new empty project" onClick={() => { setShowFileMenu(false); handleNewProject(); }} />
                  <DropdownItem icon={<FolderOpen className="w-4 h-4" />} label="Open File" title="Open a video or audio file for transcription" onClick={() => { setShowFileMenu(false); handleOpenFile(); }} />
                  <DropdownItem icon={<FileInput className="w-4 h-4" />} label="Load Project" title="Open a saved .aive project file" onClick={() => { setShowFileMenu(false); handleLoadProject(); }} />
                  <div className="border-t border-editor-border my-1" />
                  <DropdownItem icon={<Save className="w-4 h-4" />} label="Save" title="Save current project" onClick={() => { setShowFileMenu(false); handleSaveProject(); }} disabled={words.length === 0} />
                  <DropdownItem icon={<Save className="w-4 h-4" />} label="Save As" title="Save a copy of the current project" onClick={() => { setShowFileMenu(false); handleSaveProjectAs(); }} disabled={words.length === 0} />
                </div>
              </>
            )}
          </div>
            <ToolbarButton
              icon={<Scissors className="w-4 h-4" />}
              label="Cut"
              onClick={handleCut}
              active={cutMode}
              disabled={!canEdit}
              title="Cut selected word range or mark in/out area — removes the segment from output"
            />
            <ToolbarButton
              icon={<VolumeX className="w-4 h-4" />}
              label="Mute"
              onClick={handleMute}
              active={muteMode}
              disabled={!canEdit}
              title="Mute selected word range or mark in/out area — silences audio, keeps video"
            />
            <div className="flex items-center gap-1">
              <ToolbarButton
                icon={<SlidersHorizontal className="w-4 h-4" />}
                label="Sound Gain"
                onClick={handleGain}
                active={gainMode}
                disabled={!canEdit}
                title="Add gain zone from selection or mark in/out — adjust volume up or down"
              />
              <input
                type="number"
                min={-24}
                max={24}
                step={0.5}
                value={gainModeDb}
                onChange={(e) => setGainModeDb(Math.max(-24, Math.min(24, Number(e.target.value) || 0)))}
                className="w-16 px-1.5 py-1 text-xs bg-editor-surface border border-editor-border rounded text-editor-text focus:outline-none focus:border-editor-accent"
                title="Volume adjustment in decibels for new gain zones — positive boosts, negative reduces"
                disabled={!canEdit}
              />
            </div>
            <div className="flex items-center gap-1">
              <ToolbarButton
                icon={<Gauge className="w-4 h-4" />}
                label="Speed Adjust"
                onClick={handleSpeed}
                active={speedMode}
                disabled={!canEdit}
                title="Add speed zone from selection or mark in/out — change playback speed"
              />
              <input
                type="number"
                min={0.25}
                max={4}
                step={0.05}
                value={speedModeValue}
                onChange={(e) => setSpeedModeValue(Math.max(0.25, Math.min(4, Number(e.target.value) || 1)))}
                className="w-16 px-1.5 py-1 text-xs bg-editor-surface border border-editor-border rounded text-editor-text focus:outline-none focus:border-editor-accent"
                title="Playback speed multiplier for new speed zones — 1x is normal, 2x is double speed"
                disabled={!canEdit}
              />
            </div>
            <div className="w-px h-5 bg-editor-border mx-1" />
            <ToolbarButton
              icon={<Grid3x3 className="w-4 h-4" />}
              label="Edit Zones"
              active={activePanel === 'zones'}
              onClick={() => togglePanel('zones')}
              disabled={!videoPath || !canEdit}
              title="Open zone editor panel — view and manage all cut, mute, gain, and speed zones"
            />
            <ToolbarButton
              icon={<span className="text-[10px] font-semibold">PA</span>}
              label="Trim Silence"
              active={activePanel === 'silence'}
              onClick={() => togglePanel('silence')}
              disabled={!videoPath || !canEdit}
              title="Detect and remove silent pauses — batch-removes silence above a configurable threshold"
            />
            <ToolbarButton
              icon={<MapPin className="w-4 h-4" />}
              label="Chapter Marks"
              active={activePanel === 'markers'}
              onClick={() => togglePanel('markers')}
              disabled={!videoPath || !canEdit}
              title="Add and manage timeline markers — chapter points, key moments, YouTube timestamps"
            />
            <ToolbarButton
              icon={<Music className="w-4 h-4" />}
              label="Bkg. Music"
              active={activePanel === 'music'}
              onClick={() => togglePanel('music')}
              disabled={!videoPath || !canEdit}
              title="Add background music track with auto-ducking — music lowers when someone speaks"
            />
            <ToolbarButton
              icon={<ListVideo className="w-4 h-4" />}
              label="Add Clips"
              active={activePanel === 'append'}
              onClick={() => togglePanel('append')}
              disabled={!videoPath || !canEdit}
              title="Append additional video clips — concatenate multiple files during export"
            />
          <div className="w-px h-5 bg-editor-border mx-1" />
          <ToolbarButton
            icon={<Sparkles className="w-4 h-4" />}
            label="AI Tools"
            active={activePanel === 'ai'}
            onClick={() => togglePanel('ai')}
            disabled={words.length === 0 || !canEdit}
            title="AI filler detection, clip suggestions, and transcript analysis"
          />
          <ToolbarButton
            icon={<Download className="w-4 h-4" />}
            label="Export"
            active={activePanel === 'export'}
            onClick={() => togglePanel('export')}
            disabled={!videoPath}
          />
          <ToolbarButton
            icon={<Settings className="w-4 h-4" />}
            label="Settings"
            active={activePanel === 'settings'}
            onClick={() => togglePanel('settings')}
          />
          <ToolbarButton
            icon={<HelpCircle className="w-4 h-4" />}
            label="Help"
            active={activePanel === 'help'}
            onClick={() => togglePanel('help')}
            title="View help and feature documentation"
          />
        </div>
      </header>

      {/* Main content */}
      <div className="main-content flex-1 flex overflow-hidden">
        {/* Left: video + transcript */}
        <div className="flex-1 flex flex-col min-w-0">
          <div ref={splitRef} className="flex-1 flex min-h-0" style={{ position: 'relative' }}>
            {/* Video player */}
            <div className="p-3 flex items-center justify-center bg-black/20 overflow-hidden" style={{ width: `${splitRatio * 100}%`, minWidth: 0 }}>
              <VideoPlayer />
            </div>

            {/* Draggable divider */}
            <div
              tabIndex={0}
              role="separator"
              aria-label="Resize panel"
              className="w-1 shrink-0 bg-editor-border cursor-col-resize hover:bg-editor-accent/50 active:bg-editor-accent transition-colors relative z-10"
              style={{ cursor: isDraggingSplit.current ? 'col-resize' : 'col-resize' }}
              onMouseDown={startSplitDrag}
              onKeyDown={(e) => {
                if (e.key === 'ArrowLeft') setSplitRatio(Math.max(0.15, splitRatio - 0.02));
                if (e.key === 'ArrowRight') setSplitRatio(Math.min(0.85, splitRatio + 0.02));
              }}
              title="Drag to resize"
            />

            {/* Transcript */}
            <div className="border-l border-editor-border flex flex-col min-h-0" style={{ width: `${(1 - splitRatio) * 100}%`, minWidth: 0 }}>
              {videoPath && (
                <div className="flex items-center gap-2 px-3 py-1.5 border-b border-editor-border shrink-0 bg-editor-surface/50">
                  {projectName && (
                    <span className="text-xs font-semibold text-editor-accent shrink-0">{projectName}</span>
                  )}
                  <span className="text-xs font-medium truncate text-editor-text">{videoPath.split(/[/\\]/).pop()}</span>
                  <span className="text-xs text-editor-text-muted ml-auto shrink-0">
                                      {words.length} words &middot; {cutRanges.length} cuts &middot; {muteRanges.length} mutes &middot; {gainRanges.length} gains &middot; {speedRanges.length} speeds
                  </span>
                  {transcriptionModel && (
                    <span className="px-1.5 py-0.5 rounded border border-editor-border bg-editor-surface text-[10px] uppercase tracking-wide text-editor-text-muted shrink-0">
                      {transcriptionModel}
                    </span>
                  )}
                </div>
              )}
              {isTranscribing ? (
                <div className="flex-1 flex flex-col items-center justify-center gap-5">
                  {/* Animated waveform */}
                  <div className="flex items-end gap-[3px] h-10">
                    {[35, 60, 45, 80, 55, 70, 40, 65, 50, 75, 40, 58].map((h, i) => (
                      <div
                        key={i}
                        className="w-[5px] rounded-full bg-editor-accent wave-bar"
                        style={{
                          height: `${h}%`,
                          animationDelay: `${i * 75}ms`,
                        }}
                      />
                    ))}
                  </div>
                  <div className="text-center space-y-1">
                    <p className="text-sm font-medium text-editor-text">Processing audio</p>
                    <p className="text-xs text-editor-text-muted">{transcriptionStatus || 'Please wait...'}</p>
                    <div className="w-48 h-1.5 bg-editor-border rounded-full overflow-hidden mt-3">
                      <div className="h-full bg-editor-accent rounded-full animate-pulse" style={{ width: '60%' }} />
                    </div>
                  </div>
                </div>
              ) : words.length > 0 ? (
                <TranscriptEditor
                  cutMode={cutMode}
                  muteMode={muteMode}
                  gainMode={gainMode}
                  gainModeDb={gainModeDb}
                  speedMode={speedMode}
                  speedModeValue={speedModeValue}
                />
              ) : (
                <div className="flex-1 flex items-center justify-center text-editor-text-muted text-sm">
                  No transcript yet
                </div>
              )}
            </div>
          </div>

          {/* Waveform timeline */}
          <div className="h-32 border-t border-editor-border shrink-0">
            <WaveformTimeline
              cutMode={cutMode}
              muteMode={muteMode}
              gainMode={gainMode}
              gainModeDb={gainModeDb}
              speedMode={speedMode}
              speedModeValue={speedModeValue}
            />
          </div>
        </div>

        {/* Right panel (AI / Export / Settings) */}
        {activePanel && (
          <div className="flex shrink-0">
            {/* Draggable sidebar divider */}
            <div
              tabIndex={0}
              role="separator"
              aria-label="Resize panel"
              className="w-1 shrink-0 bg-editor-border cursor-col-resize hover:bg-editor-accent/50 active:bg-editor-accent transition-colors relative z-10"
              onMouseDown={startSidebarDrag}
              onKeyDown={(e) => {
                if (e.key === 'ArrowUp') setSidebarWidth(Math.max(180, sidebarWidth - sidebarWidth * 0.02));
                if (e.key === 'ArrowDown') setSidebarWidth(Math.min(600, sidebarWidth + sidebarWidth * 0.02));
              }}
              title="Drag to resize"
            />
            <div className="overflow-y-auto" style={{ width: sidebarWidth }}>
            {activePanel === 'zones' && (
              <ZoneEditor />
            )}
            {activePanel === 'silence' && <SilenceTrimmerPanel />}
            {activePanel === 'markers' && <MarkersPanel />}
            {activePanel === 'music' && <BackgroundMusicPanel />}
            {activePanel === 'append' && <AppendClipPanel />}
            {activePanel === 'ai' && <AIPanel onReprocess={handleReprocessProject} whisperModel={whisperModel} setWhisperModel={setWhisperModel} />}
            {activePanel === 'export' && <ExportDialog />}
            {activePanel === 'settings' && <SettingsPanel />}
            {activePanel === 'help' && <HelpContent />}
          </div>
        </div>
      )}
      </div>
      {import.meta.env.DEV && <DevPanel />}

      <LicenseDialog />

      {showWelcomeOverlay && (
        <div className="fixed inset-0 z-[85] flex items-center justify-center bg-black/70 px-4">
          <div className="w-full max-w-sm rounded-xl border border-editor-border bg-editor-bg p-6 space-y-5 shadow-2xl">
            <div className="flex flex-col items-center gap-3 text-center">
              <Film className="w-10 h-10 text-editor-accent opacity-80" />
              <h2 className="text-lg font-semibold">Welcome to TalkEdit</h2>
              <p className="text-xs text-editor-text-muted leading-relaxed">
                The offline video editor for long-form content. No account. No subscription. Your data never leaves your machine.
              </p>
            </div>

            <div className="space-y-3">
              <div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
                <span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">1</span>
                <span className="text-xs text-editor-text-muted leading-relaxed">
                  <strong className="text-editor-text">Open a video</strong> — TalkEdit transcribes it into a word-level transcript.
                </span>
              </div>
              <div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
                <span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">2</span>
                <span className="text-xs text-editor-text-muted leading-relaxed">
                  <strong className="text-editor-text">Edit by selecting words</strong> — deleting words cuts the matching video. Like editing a doc.
                </span>
              </div>
              <div className="flex items-start gap-3 p-2 rounded bg-editor-surface">
                <span className="w-5 h-5 rounded-full bg-editor-accent/20 text-editor-accent text-[10px] font-semibold flex items-center justify-center shrink-0 mt-0.5">3</span>
                <span className="text-xs text-editor-text-muted leading-relaxed">
                  <strong className="text-editor-text">Export your final cut</strong> — with captions, background music, AI cleanup, and more.
                </span>
              </div>
            </div>

            <div className="flex flex-col items-center gap-2">
              <button
                onClick={() => { localStorage.setItem('talkedit:welcomeDismissed', 'true'); setShowWelcomeOverlay(false); }}
                className="w-full px-6 py-2.5 bg-editor-accent hover:bg-editor-accent-hover rounded-lg text-sm font-medium transition-colors"
              >
                Got it
              </button>
              <p className="text-[10px] text-editor-text-muted">
                Press <kbd className="px-1 py-0.5 text-[10px] font-mono bg-editor-surface border border-editor-border rounded">?</kbd> anytime to see shortcuts, or click <strong className="text-editor-text">Help</strong> in the toolbar.
              </p>
            </div>
          </div>
        </div>
      )}

      {showReprocessConfirm && (
        <div
          className="fixed inset-0 z-[60] flex items-center justify-center bg-black/60 px-4"
          onClick={() => setShowReprocessConfirm(false)}
        >
          <div
            className="w-full max-w-md rounded-xl border border-editor-border bg-editor-bg p-4 space-y-3"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="text-sm font-semibold">Reprocess transcript?</h3>
            <p className="text-xs text-editor-text-muted leading-relaxed">
              This will reprocess the current file with <span className="text-editor-text font-medium">{whisperModel}</span> and replace the current transcript words and timings.
            </p>
            <div className="flex items-center justify-end gap-2 pt-1">
              <button
                onClick={() => setShowReprocessConfirm(false)}
                className="px-3 py-1.5 rounded-md text-xs text-editor-text-muted hover:text-editor-text hover:bg-editor-surface"
              >
                Cancel
              </button>
              <button
                onClick={confirmReprocessProject}
                className="px-3 py-1.5 rounded-md text-xs bg-editor-accent hover:bg-editor-accent-hover text-white"
              >
                Reprocess Now
              </button>
            </div>
          </div>
        </div>
      )}

      {showUnsavedPrompt && (
        <div
          className="fixed inset-0 z-[70] flex items-center justify-center bg-black/60 px-4"
          onClick={handleUnsavedCancel}
        >
          <div
            className="w-full max-w-md rounded-xl border border-editor-border bg-editor-bg p-4 space-y-3"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="text-sm font-semibold">Save changes first?</h3>
            <p className="text-xs text-editor-text-muted leading-relaxed">
              There are unsaved changes in this project. Save before continuing?
            </p>
            <div className="flex items-center justify-end gap-2 pt-1">
              <button
                onClick={handleUnsavedCancel}
                className="px-3 py-1.5 rounded-md text-xs text-editor-text-muted hover:text-editor-text hover:bg-editor-surface"
              >
                Cancel
              </button>
              <button
                onClick={handleUnsavedDiscardAndContinue}
                className="px-3 py-1.5 rounded-md text-xs text-editor-text hover:bg-editor-surface"
              >
                Don't Save
              </button>
              <button
                onClick={handleUnsavedSaveAndContinue}
                className="px-3 py-1.5 rounded-md text-xs bg-editor-accent hover:bg-editor-accent-hover text-white"
              >
                Save
              </button>
            </div>
          </div>
        </div>
      )}

      {showRecoveryDialog && (
        <div
          className="fixed inset-0 z-[80] flex items-center justify-center bg-black/60 px-4"
          onClick={handleDismissRecovery}
        >
          <div
            className="w-full max-w-md rounded-xl border border-editor-border bg-editor-bg p-4 space-y-3"
            onClick={(e) => e.stopPropagation()}
          >
            <h3 className="text-sm font-semibold">Recover unsaved work?</h3>
            <p className="text-xs text-editor-text-muted leading-relaxed">
              TalkEdit recovered a project from {recoveryMinutesAgo} minute{recoveryMinutesAgo !== 1 ? 's' : ''} ago.
            </p>
            <div className="flex items-center justify-end gap-2 pt-1">
              <button
                onClick={handleDismissRecovery}
                className="px-3 py-1.5 rounded-md text-xs text-editor-text-muted hover:text-editor-text hover:bg-editor-surface"
              >
                Dismiss
              </button>
              <button
                onClick={handleRecoverAutosave}
                className="px-3 py-1.5 rounded-md text-xs bg-editor-accent hover:bg-editor-accent-hover text-white"
              >
                Recover
              </button>
            </div>
          </div>
        </div>
      )}

      {backendDown && (
        <div className="fixed bottom-0 left-0 right-0 z-[90] flex items-center justify-center gap-2 px-4 py-2 bg-amber-500/15 border-t border-amber-500/30 text-amber-400 text-xs font-medium">
          <AlertTriangle className="w-3.5 h-3.5" />
          Backend disconnected — retrying...
        </div>
      )}
    </div>
  );
}

function ToolbarButton({
  icon,
  label,
  active,
  onClick,
  disabled,
  title,
}: {
  icon: React.ReactNode;
  label: string;
  active?: boolean;
  onClick: () => void;
  disabled?: boolean;
  title?: string;
}) {
  return (
    <span title={title || label}>
      <button
        onClick={onClick}
        disabled={disabled}
        className={`flex items-center gap-1.5 px-3 py-1.5 rounded-md text-xs font-medium transition-colors ${
          active
            ? 'bg-editor-accent text-white'
            : 'text-editor-text-muted hover:text-editor-text hover:bg-editor-surface'
        } ${disabled ? 'opacity-40 cursor-not-allowed' : ''}`}
      >
        {icon}
        {label}
      </button>
    </span>
  );
}

function DropdownItem({
  icon,
  label,
  onClick,
  disabled,
  title,
}: {
  icon: React.ReactNode;
  label: string;
  onClick: () => void;
  disabled?: boolean;
  title?: string;
}) {
  return (
    <span title={title || label}>
      <button
        onClick={onClick}
        disabled={disabled}
        className={`w-full flex items-center gap-2 px-3 py-1.5 text-xs text-left transition-colors ${
          disabled
            ? 'opacity-40 cursor-not-allowed'
            : 'text-editor-text-muted hover:text-editor-text hover:bg-editor-bg'
        }`}
      >
        {icon}
        {label}
      </button>
    </span>
  );
}
