<template>
  <div class="terminal-wrapper flex flex-col h-full relative">
    <!-- Inline terminal search bar — shown when Ctrl+F is pressed -->
    <div
      v-if="searchVisible"
      class="absolute top-2 right-2 z-20 flex items-center gap-1 bg-[#161b22] border border-[#30363d] rounded-lg shadow-lg px-2 py-1"
    >
      <input
        ref="searchInputRef"
        v-model="searchQuery"
        type="text"
        placeholder="Find in terminal…"
        class="w-48 px-1.5 py-0.5 text-xs bg-[var(--wraith-bg-tertiary)] border border-[var(--wraith-border)] text-[var(--wraith-text-primary)] placeholder-[var(--wraith-text-muted)] outline-none focus:border-[var(--wraith-accent-blue)] rounded transition-colors"
        @keydown.enter="findNext"
        @keydown.shift.enter.prevent="findPrevious"
        @keydown.escape="closeSearch"
        @input="onSearchInput"
      />
      <button
        class="p-1 text-[var(--wraith-text-muted)] hover:text-[var(--wraith-text-primary)] transition-colors cursor-pointer"
        title="Previous match (Shift+Enter)"
        @click="findPrevious"
      >
        <svg class="w-3 h-3" viewBox="0 0 16 16" fill="currentColor">
          <path d="M4.427 9.573 8 6l3.573 3.573a.75.75 0 0 0 1.06-1.06L8.53 4.409a.75.75 0 0 0-1.06 0L3.367 8.513a.75.75 0 0 0 1.06 1.06z" />
        </svg>
      </button>
      <button
        class="p-1 text-[var(--wraith-text-muted)] hover:text-[var(--wraith-text-primary)] transition-colors cursor-pointer"
        title="Next match (Enter)"
        @click="findNext"
      >
        <svg class="w-3 h-3" viewBox="0 0 16 16" fill="currentColor">
          <path d="M4.427 6.427 8 10l3.573-3.573a.75.75 0 0 1 1.06 1.06L8.53 11.591a.75.75 0 0 1-1.06 0L3.367 7.487a.75.75 0 0 1 1.06-1.06z" />
        </svg>
      </button>
      <button
        class="p-1 text-[var(--wraith-text-muted)] hover:text-[var(--wraith-accent-red)] transition-colors cursor-pointer"
        title="Close (Esc)"
        @click="closeSearch"
      >
        <svg class="w-3 h-3" viewBox="0 0 16 16" fill="currentColor">
          <path d="M3.72 3.72a.75.75 0 0 1 1.06 0L8 6.94l3.22-3.22a.749.749 0 0 1 1.275.326.749.749 0 0 1-.215.734L9.06 8l3.22 3.22a.749.749 0 0 1-.326 1.275.749.749 0 0 1-.734-.215L8 9.06l-3.22 3.22a.751.751 0 0 1-1.042-.018.751.751 0 0 1-.018-1.042L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06z" />
        </svg>
      </button>
    </div>

    <!-- Terminal container -->
    <div
      ref="containerRef"
      class="terminal-container flex-1"
      @click="handleFocus"
      @focus="handleFocus"
    />

    <!-- Remote monitoring bar -->
    <MonitorBar :session-id="props.sessionId" />
  </div>
</template>

<script setup lang="ts">
import { ref, nextTick, onMounted, onBeforeUnmount, watch } from "vue";
import { invoke } from "@tauri-apps/api/core";
import { useTerminal } from "@/composables/useTerminal";
import { useSessionStore } from "@/stores/session.store";
import MonitorBar from "@/components/terminal/MonitorBar.vue";
import type { IDisposable } from "@xterm/xterm";
import "@/assets/css/terminal.css";

const props = defineProps<{
  sessionId: string;
  isActive: boolean;
}>();

const sessionStore = useSessionStore();
const containerRef = ref<HTMLElement | null>(null);
const { terminal, searchAddon, mount, fit } = useTerminal(props.sessionId);
let resizeDisposable: IDisposable | null = null;

// --- Search state ---
const searchVisible = ref(false);
const searchQuery = ref("");
const searchInputRef = ref<HTMLInputElement | null>(null);

/** Open the inline search bar and focus it. */
function openSearch(): void {
  searchVisible.value = true;
  nextTick(() => {
    searchInputRef.value?.focus();
    searchInputRef.value?.select();
  });
}

/** Close the search bar and refocus the terminal. */
function closeSearch(): void {
  searchVisible.value = false;
  searchQuery.value = "";
  terminal.focus();
}

/** Decoration options for search highlights — xterm SearchAddon spec. */
const searchDecorations = {
  matchBackground: "#f0883e40",
  matchBorder: "#f0883e",
  matchOverviewRuler: "#f0883e",
  activeMatchBackground: "#f0883e80",
  activeMatchBorder: "#f0883e",
  activeMatchColorOverviewRuler: "#f0883e",
} as const;

/** Find the next match. */
function findNext(): void {
  if (!searchQuery.value) return;
  searchAddon.findNext(searchQuery.value, { caseSensitive: false, decorations: searchDecorations });
}

/** Find the previous match. */
function findPrevious(): void {
  if (!searchQuery.value) return;
  searchAddon.findPrevious(searchQuery.value, { caseSensitive: false, decorations: searchDecorations });
}

/** Re-search as the user types. */
function onSearchInput(): void {
  if (searchQuery.value) {
    findNext();
  }
}

// Expose openSearch so SessionContainer / MainLayout can trigger Ctrl+F
defineExpose({ openSearch });

onMounted(() => {
  if (containerRef.value) {
    mount(containerRef.value);
  }

  // Apply the current theme immediately if one is already active
  if (sessionStore.activeTheme) {
    applyTheme();
  }

  // Track terminal dimensions in the session store
  resizeDisposable = terminal.onResize(({ cols, rows }) => {
    sessionStore.setTerminalDimensions(props.sessionId, cols, rows);
  });

  // Focus the terminal after mount so keyboard input works immediately
  setTimeout(() => {
    fit();
    terminal.focus();
  }, 50);
});

// Re-fit and focus terminal when switching back to this tab.
// Must wait for the container to have real dimensions after becoming visible.
watch(
  () => props.isActive,
  (active) => {
    if (active) {
      // Double rAF ensures the container has been laid out by the browser
      requestAnimationFrame(() => {
        requestAnimationFrame(() => {
          fit();
          terminal.focus();
          // Also notify the backend of the correct size
          const session = sessionStore.sessions.find(s => s.id === props.sessionId);
          const resizeCmd = session?.protocol === "local" ? "pty_resize" : "ssh_resize";
          invoke(resizeCmd, {
            sessionId: props.sessionId,
            cols: terminal.cols,
            rows: terminal.rows,
          }).catch(() => {});
        });
      });
    }
  },
);

/** Apply the session store's active theme to this terminal instance. */
function applyTheme(): void {
  const theme = sessionStore.activeTheme;
  if (!theme) return;
  terminal.options.theme = {
    background: theme.background,
    foreground: theme.foreground,
    cursor: theme.cursor,
    black: theme.black,
    red: theme.red,
    green: theme.green,
    yellow: theme.yellow,
    blue: theme.blue,
    magenta: theme.magenta,
    cyan: theme.cyan,
    white: theme.white,
    brightBlack: theme.brightBlack,
    brightRed: theme.brightRed,
    brightGreen: theme.brightGreen,
    brightYellow: theme.brightYellow,
    brightBlue: theme.brightBlue,
    brightMagenta: theme.brightMagenta,
    brightCyan: theme.brightCyan,
    brightWhite: theme.brightWhite,
  };
}

// Watch for theme changes in the session store and apply to this terminal
watch(() => sessionStore.activeTheme, (newTheme) => {
  if (newTheme) applyTheme();
});

onBeforeUnmount(() => {
  if (resizeDisposable) {
    resizeDisposable.dispose();
    resizeDisposable = null;
  }
});

function handleFocus(): void {
  terminal.focus();
}
</script>
