<script lang="ts">
  import { onMount, onDestroy } from "svelte";
  import { invoke } from "@tauri-apps/api/core";
  import { get } from "svelte/store";
  import { initializeTauriListeners, cleanupTauriListeners } from "$lib/tauri";
  import { configStore, applyTheme, applyFontSize, isCompactMode } from "$lib/stores/config";
  import { initNotificationSync, cleanupNotificationSync } from "$lib/stores/notifications";
  import { conversationsStore } from "$lib/stores/conversations";
  import { claudeStore, isClaudeProcessing } from "$lib/stores/claude";
  import { editorStore } from "$lib/stores/editor";
  import { getCurrentWindow, LogicalSize } from "@tauri-apps/api/window";
  import "$lib/notifications/testNotifications";
  import Terminal from "$lib/components/Terminal.svelte";
  import InputBar from "$lib/components/InputBar.svelte";
  import StatusBar from "$lib/components/StatusBar.svelte";
  import AnimeGirl from "$lib/components/AnimeGirl.svelte";
  import CompactMode from "$lib/components/CompactMode.svelte";
  import EditorPanel from "$lib/components/editor/EditorPanel.svelte";
  import { characterState } from "$lib/stores/character";
  import type { CharacterState } from "$lib/types/states";
  import PermissionModal from "$lib/components/PermissionModal.svelte";
  import UserQuestionModal from "$lib/components/UserQuestionModal.svelte";
  import ConfigSidebar from "$lib/components/ConfigSidebar.svelte";
  import AchievementNotification from "$lib/components/AchievementNotification.svelte";
  import AchievementsPanel from "$lib/components/AchievementsPanel.svelte";
  import UpdateNotification from "$lib/components/UpdateNotification.svelte";

  let initialized = false;
  let updateNotification: UpdateNotification | undefined = $state(undefined);
  let achievementPanelOpen = $state(false);
  let currentCharacterState: CharacterState = $state("idle");
  let compactModeActive = $state(false);

  // Editor state
  const isEditorVisible = editorStore.isEditorVisible;
  let lastInitializedCwd = "";

  // Track connection status and CWD for the editor
  const connectionStatus = claudeStore.connectionStatus;
  const currentWorkingDirectory = claudeStore.currentWorkingDirectory;

  // Initialize/update editor file tree when CWD changes while editor is visible
  $effect(() => {
    const visible = $isEditorVisible;
    const cwd = $currentWorkingDirectory;
    const connected = $connectionStatus === "connected";

    // Only initialize when editor is visible, connected, and CWD is set
    if (visible && connected && cwd && cwd !== lastInitializedCwd) {
      lastInitializedCwd = cwd;
      editorStore.initializeFileTree(cwd);
    }

    // Hide editor if disconnected
    if (!connected && visible) {
      editorStore.hideEditor();
    }
  });

  // Window size constants
  const COMPACT_WIDTH = 280;
  const COMPACT_HEIGHT = 400;

  // Store the previous window size to restore when exiting compact mode
  let previousWindowSize: { width: number; height: number } | null = null;

  characterState.subscribe((state) => {
    currentCharacterState = state;
  });

  isCompactMode.subscribe((value) => {
    compactModeActive = value;
  });

  function getPanelGlowClass(): string {
    switch (currentCharacterState) {
      case "thinking":
        return "panel-glow-thinking";
      case "typing":
        return "panel-glow-typing";
      case "searching":
        return "panel-glow-searching";
      case "coding":
        return "panel-glow-coding";
      case "mcp":
        return "panel-glow-mcp";
      case "success":
        return "panel-glow-success";
      case "error":
        return "panel-glow-error";
      default:
        return "";
    }
  }

  // Resizable panel state
  let panelWidth = $state(320); // Default width in pixels
  let isResizing = $state(false);
  const MIN_PANEL_WIDTH = 200;
  const MAX_PANEL_WIDTH = 600;

  function startResize(event: MouseEvent) {
    isResizing = true;
    event.preventDefault();
    document.addEventListener("mousemove", handleResize);
    document.addEventListener("mouseup", stopResize);
  }

  function handleResize(event: MouseEvent) {
    if (!isResizing) return;
    const newWidth = event.clientX;
    panelWidth = Math.max(MIN_PANEL_WIDTH, Math.min(MAX_PANEL_WIDTH, newWidth));
  }

  function stopResize() {
    if (isResizing) {
      isResizing = false;
      document.removeEventListener("mousemove", handleResize);
      document.removeEventListener("mouseup", stopResize);
      // Save the panel width to config
      configStore.updateConfig({ character_panel_width: panelWidth });
    }
  }

  // Global keyboard shortcuts
  function handleGlobalKeydown(event: KeyboardEvent) {
    // Don't trigger shortcuts when typing in inputs (except for specific ones)
    const target = event.target as HTMLElement;
    const isInputFocused = target.tagName === "INPUT" || target.tagName === "TEXTAREA";

    // Escape closes panels (always works)
    if (event.key === "Escape") {
      // Check if any panels are open and close them
      if (achievementPanelOpen) {
        achievementPanelOpen = false;
        event.preventDefault();
        return;
      }
      // ConfigSidebar handles its own escape via store
      if (get(configStore.isSidebarOpen)) {
        configStore.closeSidebar();
        event.preventDefault();
        return;
      }
    }

    // Skip other shortcuts if user is typing in an input
    if (isInputFocused) return;

    // Ctrl+L - Clear terminal
    if (event.ctrlKey && event.key === "l") {
      event.preventDefault();
      claudeStore.clearTerminal();
      return;
    }

    // Ctrl+, - Open settings
    if (event.ctrlKey && event.key === ",") {
      event.preventDefault();
      configStore.openSidebar();
      return;
    }

    // Ctrl+C - Interrupt (only when processing)
    if (event.ctrlKey && event.key === "c") {
      if (get(isClaudeProcessing)) {
        event.preventDefault();
        handleInterrupt();
        return;
      }
    }

    // Ctrl++ or Ctrl+= - Increase font size
    if (event.ctrlKey && (event.key === "+" || event.key === "=")) {
      event.preventDefault();
      configStore.increaseFontSize();
      return;
    }

    // Ctrl+- - Decrease font size
    if (event.ctrlKey && event.key === "-") {
      event.preventDefault();
      configStore.decreaseFontSize();
      return;
    }

    // Ctrl+0 - Reset font size
    if (event.ctrlKey && event.key === "0") {
      event.preventDefault();
      configStore.resetFontSize();
      return;
    }

    // Ctrl+Shift+S - Toggle streamer mode
    if (event.ctrlKey && event.shiftKey && event.key === "S") {
      event.preventDefault();
      configStore.toggleStreamerMode();
      return;
    }

    // Ctrl+Shift+M - Toggle compact mode
    if (event.ctrlKey && event.shiftKey && event.key === "M") {
      event.preventDefault();
      toggleCompactMode();
      return;
    }

    // Ctrl+E - Toggle editor panel (only when connected)
    if (event.ctrlKey && event.key === "e") {
      event.preventDefault();
      // Only allow opening the editor when connected
      if (get(claudeStore.connectionStatus) === "connected") {
        editorStore.toggleEditor();
      }
      return;
    }

    // Ctrl+B - Toggle file browser (when editor is visible)
    if (event.ctrlKey && event.key === "b" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      editorStore.toggleFileBrowser();
      return;
    }

    // Ctrl+S - Save current file (when editor is visible)
    if (event.ctrlKey && event.key === "s" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      editorStore.saveFile();
      return;
    }

    // Ctrl+W - Close current tab (when editor is visible)
    if (event.ctrlKey && event.key === "w" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      const activeTabId = get(editorStore.activeTabId);
      if (activeTabId) {
        editorStore.closeTab(activeTabId);
      }
      return;
    }

    // Ctrl+N - New file (when editor is visible)
    // Note: This just emits an event that FileBrowser listens to
    if (event.ctrlKey && event.key === "n" && get(editorStore.isEditorVisible)) {
      event.preventDefault();
      // Dispatch a custom event that FileBrowser will listen to
      window.dispatchEvent(new CustomEvent("editor-new-file"));
      return;
    }
  }

  async function handleInterrupt() {
    try {
      const conversationId = get(claudeStore.activeConversationId);
      if (!conversationId) return;

      await invoke("interrupt_claude", { conversationId });
      claudeStore.addLine("system", "Process interrupted");
    } catch (error) {
      console.error("Failed to interrupt:", error);
    }
  }

  async function enterCompactMode() {
    try {
      const window = getCurrentWindow();
      const currentSize = await window.innerSize();
      const scaleFactor = await window.scaleFactor();

      // Save current window size (convert from physical to logical pixels)
      // innerSize() returns physical pixels, but setSize() with LogicalSize expects logical
      previousWindowSize = {
        width: Math.round(currentSize.width / scaleFactor),
        height: Math.round(currentSize.height / scaleFactor),
      };

      // Resize to compact dimensions
      await window.setSize(new LogicalSize(COMPACT_WIDTH, COMPACT_HEIGHT));

      // Enable compact mode in config
      await configStore.setCompactMode(true);
    } catch (error) {
      console.error("Failed to enter compact mode:", error);
    }
  }

  async function exitCompactMode() {
    try {
      const window = getCurrentWindow();

      // Only resize if we have a saved previous size
      // (i.e., user entered compact mode during this session)
      // Otherwise, just expand to a reasonable default
      if (previousWindowSize) {
        await window.setSize(new LogicalSize(previousWindowSize.width, previousWindowSize.height));
        previousWindowSize = null;
      } else {
        // No saved size (e.g., app started in compact mode) - use modest default
        await window.setSize(new LogicalSize(900, 650));
      }

      // Disable compact mode in config
      await configStore.setCompactMode(false);
    } catch (error) {
      console.error("Failed to exit compact mode:", error);
    }
  }

  async function toggleCompactMode() {
    if (compactModeActive) {
      await exitCompactMode();
    } else {
      await enterCompactMode();
    }
  }

  onMount(async () => {
    if (!initialized) {
      initialized = true;

      // Initialize conversations store first to ensure activeConversationId is set
      conversationsStore.initialize();

      await initializeTauriListeners();
      await configStore.loadConfig();

      // Apply saved settings on startup
      const config = configStore.getConfig();
      applyTheme(config.theme, config.custom_theme_colors);
      applyFontSize(config.font_size);

      // Apply always-on-top setting
      if (config.always_on_top) {
        const window = getCurrentWindow();
        await window.setAlwaysOnTop(true);
      }

      // Load saved panel width
      if (config.character_panel_width) {
        panelWidth = config.character_panel_width;
      }

      // Initialize notification settings sync
      initNotificationSync();

      // Add global keyboard shortcut listener
      window.addEventListener("keydown", handleGlobalKeydown);

      // Check for updates on startup
      if (config.update_checks_enabled) {
        updateNotification?.checkForUpdates();
      }

      // Apply compact mode if saved (resize window)
      if (config.compact_mode) {
        const window = getCurrentWindow();
        await window.setSize(new LogicalSize(COMPACT_WIDTH, COMPACT_HEIGHT));
      }
    }
  });

  onDestroy(() => {
    if (initialized) {
      cleanupTauriListeners();
      cleanupNotificationSync();
      window.removeEventListener("keydown", handleGlobalKeydown);
      initialized = false;
    }
  });
</script>

{#if compactModeActive}
  <!-- Compact mode: minimal widget interface -->
  <div
    class="app-container compact-app h-screen w-screen flex flex-col bg-[var(--bg-primary)] overflow-hidden"
  >
    <CompactMode onExpand={exitCompactMode} />
  </div>
{:else}
  <!-- Full mode: standard interface -->
  <div class="app-container h-screen w-screen flex flex-col bg-[var(--bg-primary)] overflow-hidden">
    <StatusBar
      onToggleAchievements={() => (achievementPanelOpen = !achievementPanelOpen)}
      onToggleCompact={enterCompactMode}
    />

    <main class="flex-1 flex overflow-hidden">
      <!-- Left panel: Character display -->
      <div
        class="character-panel {getPanelGlowClass()} flex flex-col items-center justify-center bg-[var(--bg-secondary)]/50"
        style="width: {panelWidth}px; min-width: {MIN_PANEL_WIDTH}px; max-width: {MAX_PANEL_WIDTH}px;"
      >
        <AnimeGirl />
      </div>

      <!-- Resize handle -->
      <!-- svelte-ignore a11y_no_static_element_interactions -->
      <div
        class="resize-handle w-1 cursor-col-resize bg-[var(--border-color)] hover:bg-[var(--accent-primary)] transition-colors flex-shrink-0"
        class:bg-[var(--accent-primary)]={isResizing}
        onmousedown={startResize}
      ></div>

      <!-- Right panel: Terminal/Editor and input -->
      <div class="terminal-panel flex-1 flex flex-col min-w-0">
        {#if $isEditorVisible}
          <EditorPanel />
        {:else}
          <Terminal />
          <InputBar />
        {/if}
      </div>
    </main>

    <PermissionModal />
    <UserQuestionModal />
    <ConfigSidebar />
    <AchievementNotification />
    <AchievementsPanel
      bind:isOpen={achievementPanelOpen}
      onClose={() => (achievementPanelOpen = false)}
    />
    <UpdateNotification bind:this={updateNotification} />
  </div>
{/if}

<style>
  .app-container {
    font-family:
      "Inter",
      -apple-system,
      BlinkMacSystemFont,
      "Segoe UI",
      Roboto,
      sans-serif;
  }

  .character-panel {
    background: linear-gradient(180deg, var(--bg-secondary) 0%, var(--bg-primary) 100%);
    transition: all 0.5s ease;
    position: relative;
  }

  .character-panel::before {
    content: "";
    position: absolute;
    inset: 0;
    padding: 3px;
    background: transparent;
    -webkit-mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
    mask:
      linear-gradient(#fff 0 0) content-box,
      linear-gradient(#fff 0 0);
    -webkit-mask-composite: xor;
    mask-composite: exclude;
    opacity: 0;
    transition: opacity 0.5s ease;
    pointer-events: none;
  }

  /* Trans pride gradient glow effects for the character panel */
  .panel-glow-thinking {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #9333ea) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(147, 51, 234, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-thinking::before {
    background: linear-gradient(180deg, #9333ea, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-typing {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #3b82f6) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(59, 130, 246, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.15),
      0 0 40px rgba(91, 206, 250, 0.25),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-typing::before {
    background: linear-gradient(180deg, #3b82f6, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-searching {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #eab308) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(234, 179, 8, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-searching::before {
    background: linear-gradient(180deg, #eab308, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-coding {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #22c55e) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(34, 197, 94, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-coding::before {
    background: linear-gradient(180deg, #22c55e, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-mcp {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 80%, var(--trans-blue)) 0%,
      color-mix(in srgb, var(--bg-primary) 85%, var(--trans-pink)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 100%
    );
    box-shadow:
      inset 0 0 80px rgba(91, 206, 250, 0.2),
      inset 0 0 120px rgba(245, 169, 184, 0.15),
      0 0 60px rgba(91, 206, 250, 0.3),
      0 0 100px rgba(245, 169, 184, 0.2);
  }

  .panel-glow-mcp::before {
    background: var(--trans-gradient-vibrant);
    opacity: 1;
  }

  .panel-glow-success {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 85%, #10b981) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-blue)) 50%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(16, 185, 129, 0.15),
      inset 0 0 100px rgba(91, 206, 250, 0.1),
      0 0 40px rgba(91, 206, 250, 0.2),
      0 0 80px rgba(245, 169, 184, 0.15);
  }

  .panel-glow-success::before {
    background: linear-gradient(180deg, #10b981, var(--trans-blue), var(--trans-pink));
    opacity: 1;
  }

  .panel-glow-error {
    background: linear-gradient(
      180deg,
      color-mix(in srgb, var(--bg-secondary) 80%, #ef4444) 0%,
      color-mix(in srgb, var(--bg-primary) 90%, var(--trans-pink)) 50%,
      color-mix(in srgb, var(--bg-primary) 95%, var(--trans-blue)) 100%
    );
    box-shadow:
      inset 0 0 60px rgba(239, 68, 68, 0.2),
      inset 0 0 100px rgba(245, 169, 184, 0.1),
      0 0 40px rgba(245, 169, 184, 0.2),
      0 0 80px rgba(239, 68, 68, 0.15);
  }

  .panel-glow-error::before {
    background: linear-gradient(180deg, #ef4444, var(--trans-pink), var(--trans-blue));
    opacity: 1;
  }

  .resize-handle:hover,
  .resize-handle:active {
    width: 4px;
  }
</style>
