<template>
  <Teleport to="body">
    <div
      v-if="visible"
      class="fixed inset-0 z-50 flex items-center justify-center"
      @click.self="close"
      @keydown.esc="close"
    >
      <!-- Backdrop -->
      <div class="absolute inset-0 bg-black/50" @click="close" />

      <!-- Modal -->
      <div class="relative w-full max-w-lg bg-[#161b22] border border-[#30363d] rounded-lg shadow-2xl overflow-hidden">
        <!-- Header -->
        <div class="flex items-center justify-between px-4 py-3 border-b border-[#30363d]">
          <h3 class="text-sm font-semibold text-[var(--wraith-text-primary)]">Settings</h3>
          <button
            class="text-[var(--wraith-text-muted)] hover:text-[var(--wraith-text-primary)] transition-colors cursor-pointer"
            @click="close"
          >
            <svg class="w-4 h-4" 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 1 1 1.06 1.06L9.06 8l3.22 3.22a.749.749 0 1 1-1.06 1.06L8 9.06l-3.22 3.22a.749.749 0 1 1-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 0 1 0-1.06Z" />
            </svg>
          </button>
        </div>

        <!-- Body -->
        <div class="flex min-h-[400px] max-h-[70vh]">
          <!-- Section tabs (left sidebar) -->
          <div class="w-36 border-r border-[#30363d] py-2 shrink-0">
            <button
              v-for="section in sections"
              :key="section.id"
              class="w-full flex items-center gap-2 px-4 py-2 text-xs text-left transition-colors cursor-pointer"
              :class="activeSection === section.id
                ? 'bg-[#1f6feb]/20 text-[var(--wraith-text-primary)] border-r-2 border-[#1f6feb]'
                : 'text-[var(--wraith-text-secondary)] hover:bg-[#30363d] hover:text-[var(--wraith-text-primary)]'
              "
              @click="activeSection = section.id"
            >
              <span v-html="section.icon" />
              {{ section.label }}
            </button>
          </div>

          <!-- Section content (right panel) -->
          <div class="flex-1 overflow-y-auto p-4 space-y-4">

            <!-- General -->
            <template v-if="activeSection === 'general'">
              <h4 class="text-xs font-semibold text-[var(--wraith-text-muted)] uppercase tracking-wider mb-3">General</h4>

              <!-- Default protocol -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Default Protocol</label>
                <select
                  v-model="settings.defaultProtocol"
                  class="w-full px-3 py-2 text-sm rounded bg-[#0d1117] border border-[#30363d] text-[var(--wraith-text-primary)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors cursor-pointer"
                >
                  <option value="ssh">SSH</option>
                  <option value="rdp">RDP</option>
                </select>
                <!-- TODO: Persist via Wails binding — SettingsService.SetDefaultProtocol(value) -->
              </div>

              <!-- Sidebar width -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">
                  Sidebar Width: {{ settings.sidebarWidth }}px
                </label>
                <input
                  v-model.number="settings.sidebarWidth"
                  type="range"
                  min="180"
                  max="400"
                  step="10"
                  class="w-full accent-[var(--wraith-accent-blue)]"
                />
                <!-- TODO: Persist via Wails binding — SettingsService.SetSidebarWidth(value) -->
              </div>
            </template>

            <!-- Terminal -->
            <template v-if="activeSection === 'terminal'">
              <h4 class="text-xs font-semibold text-[var(--wraith-text-muted)] uppercase tracking-wider mb-3">Terminal</h4>

              <!-- Default theme -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Default Theme</label>
                <select
                  v-model="settings.terminalTheme"
                  class="w-full px-3 py-2 text-sm rounded bg-[#0d1117] border border-[#30363d] text-[var(--wraith-text-primary)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors cursor-pointer"
                >
                  <option v-for="theme in themeNames" :key="theme" :value="theme">{{ theme }}</option>
                </select>
                <!-- TODO: Persist via Wails binding — SettingsService.SetTerminalTheme(value) -->
              </div>

              <!-- Font size -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Font Size</label>
                <input
                  v-model.number="settings.fontSize"
                  type="number"
                  min="8"
                  max="32"
                  class="w-full px-3 py-2 text-sm rounded bg-[#0d1117] border border-[#30363d] text-[var(--wraith-text-primary)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors"
                />
                <!-- TODO: Persist via Wails binding — SettingsService.SetFontSize(value) -->
              </div>

              <!-- Scrollback buffer -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-1">Scrollback Buffer (lines)</label>
                <input
                  v-model.number="settings.scrollbackBuffer"
                  type="number"
                  min="100"
                  max="100000"
                  step="100"
                  class="w-full px-3 py-2 text-sm rounded bg-[#0d1117] border border-[#30363d] text-[var(--wraith-text-primary)] outline-none focus:border-[var(--wraith-accent-blue)] transition-colors"
                />
                <!-- TODO: Persist via Wails binding — SettingsService.SetScrollbackBuffer(value) -->
              </div>
            </template>

            <!-- Vault -->
            <template v-if="activeSection === 'vault'">
              <h4 class="text-xs font-semibold text-[var(--wraith-text-muted)] uppercase tracking-wider mb-3">Vault</h4>

              <!-- Change master password -->
              <div>
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-2">Master Password</label>
                <button
                  class="px-3 py-2 text-xs text-[var(--wraith-text-primary)] rounded border border-[#30363d] hover:bg-[#30363d] transition-colors cursor-pointer"
                  @click="changeMasterPassword"
                >
                  Change Master Password
                </button>
                <!-- TODO: Open a password change dialog via Wails binding — VaultService.ChangeMasterPassword(old, new) -->
              </div>

              <!-- Export vault -->
              <div class="pt-2">
                <label class="block text-xs text-[var(--wraith-text-secondary)] mb-2">Backup</label>
                <div class="flex gap-2">
                  <button
                    class="px-3 py-2 text-xs text-[var(--wraith-text-primary)] rounded border border-[#30363d] hover:bg-[#30363d] transition-colors cursor-pointer"
                    @click="exportVault"
                  >
                    Export Vault
                  </button>
                  <button
                    class="px-3 py-2 text-xs text-[var(--wraith-text-primary)] rounded border border-[#30363d] hover:bg-[#30363d] transition-colors cursor-pointer"
                    @click="importVault"
                  >
                    Import Vault
                  </button>
                </div>
                <!-- TODO: Wails bindings — VaultService.Export() / VaultService.Import(data) -->
              </div>
            </template>

            <!-- About -->
            <template v-if="activeSection === 'about'">
              <h4 class="text-xs font-semibold text-[var(--wraith-text-muted)] uppercase tracking-wider mb-3">About</h4>

              <div class="space-y-3">
                <div class="bg-[#0d1117] rounded-lg p-4 text-center">
                  <div class="text-lg font-bold tracking-widest text-[var(--wraith-accent-blue)] mb-1">WRAITH</div>
                  <div class="text-xs text-[var(--wraith-text-secondary)]">Connection Manager</div>
                </div>

                <div class="space-y-2 text-xs">
                  <div class="flex justify-between py-1.5 border-b border-[#30363d]">
                    <span class="text-[var(--wraith-text-secondary)]">Version</span>
                    <span class="text-[var(--wraith-text-primary)]">{{ currentVersion }}</span>
                  </div>
                  <div class="flex justify-between py-1.5 border-b border-[#30363d]">
                    <span class="text-[var(--wraith-text-secondary)]">License</span>
                    <span class="text-[var(--wraith-text-primary)]">Proprietary</span>
                  </div>
                  <div class="flex justify-between py-1.5 border-b border-[#30363d]">
                    <span class="text-[var(--wraith-text-secondary)]">Runtime</span>
                    <span class="text-[var(--wraith-text-primary)]">Wails v3</span>
                  </div>
                  <div class="flex justify-between py-1.5">
                    <span class="text-[var(--wraith-text-secondary)]">Frontend</span>
                    <span class="text-[var(--wraith-text-primary)]">Vue 3 + TypeScript</span>
                  </div>
                </div>

                <!-- Check for Updates -->
                <div class="pt-2">
                  <button
                    class="w-full px-3 py-2 text-xs rounded border transition-colors cursor-pointer flex items-center justify-center gap-2"
                    :class="updateCheckState === 'found'
                      ? 'border-[#3fb950] text-[#3fb950] hover:bg-[#3fb950]/10'
                      : 'border-[#30363d] text-[var(--wraith-text-primary)] hover:bg-[#30363d]'"
                    :disabled="updateCheckState === 'checking' || updateCheckState === 'downloading'"
                    @click="checkForUpdates"
                  >
                    <template v-if="updateCheckState === 'idle'">
                      <svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
                        <path d="M1.705 8.005a.75.75 0 0 1 .834.656 5.5 5.5 0 0 0 9.592 2.97l-1.204-1.204a.25.25 0 0 1 .177-.427h3.646a.25.25 0 0 1 .25.25v3.646a.25.25 0 0 1-.427.177l-1.38-1.38A7.002 7.002 0 0 1 1.05 8.84a.75.75 0 0 1 .656-.834ZM8 2.5a5.487 5.487 0 0 0-4.131 1.869l1.204 1.204A.25.25 0 0 1 4.896 6H1.25A.25.25 0 0 1 1 5.75V2.104a.25.25 0 0 1 .427-.177l1.38 1.38A7.002 7.002 0 0 1 14.95 7.16a.75.75 0 0 1-1.49.178A5.5 5.5 0 0 0 8 2.5Z" />
                      </svg>
                      Check for Updates
                    </template>
                    <template v-else-if="updateCheckState === 'checking'">
                      <svg class="w-3.5 h-3.5 animate-spin" viewBox="0 0 16 16" fill="currentColor">
                        <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0ZM1.5 8a6.5 6.5 0 1 1 13 0 6.5 6.5 0 0 1-13 0Z" opacity=".25" />
                        <path d="M8 0a8 8 0 0 1 8 8h-1.5A6.5 6.5 0 0 0 8 1.5V0Z" />
                      </svg>
                      Checking...
                    </template>
                    <template v-else-if="updateCheckState === 'found'">
                      <svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
                        <path d="M8 2a6 6 0 1 0 0 12A6 6 0 0 0 8 2Zm.75 3.5v3.69l1.72-1.72a.75.75 0 1 1 1.06 1.06l-3 3a.75.75 0 0 1-1.06 0l-3-3a.75.75 0 1 1 1.06-1.06l1.72 1.72V5.5a.75.75 0 0 1 1.5 0Z" />
                      </svg>
                      v{{ latestVersion }} available — click to download
                    </template>
                    <template v-else-if="updateCheckState === 'downloading'">
                      <svg class="w-3.5 h-3.5 animate-spin" viewBox="0 0 16 16" fill="currentColor">
                        <path d="M8 0a8 8 0 1 0 0 16A8 8 0 0 0 8 0ZM1.5 8a6.5 6.5 0 1 1 13 0 6.5 6.5 0 0 1-13 0Z" opacity=".25" />
                        <path d="M8 0a8 8 0 0 1 8 8h-1.5A6.5 6.5 0 0 0 8 1.5V0Z" />
                      </svg>
                      Downloading...
                    </template>
                    <template v-else-if="updateCheckState === 'up-to-date'">
                      <svg class="w-3.5 h-3.5" viewBox="0 0 16 16" fill="currentColor">
                        <path d="M13.78 4.22a.75.75 0 0 1 0 1.06l-7.25 7.25a.75.75 0 0 1-1.06 0L2.22 9.28a.751.751 0 0 1 .018-1.042.751.751 0 0 1 1.042-.018L6 10.94l6.72-6.72a.75.75 0 0 1 1.06 0Z" />
                      </svg>
                      You're up to date
                    </template>
                    <template v-else-if="updateCheckState === 'error'">
                      Could not check for updates
                    </template>
                  </button>
                </div>

                <div class="flex gap-2 pt-2">
                  <a
                    href="#"
                    class="flex-1 px-3 py-2 text-xs text-center text-[var(--wraith-accent-blue)] rounded border border-[#30363d] hover:bg-[#30363d] transition-colors cursor-pointer"
                    @click.prevent="openLink('docs')"
                  >
                    Documentation
                  </a>
                  <a
                    href="#"
                    class="flex-1 px-3 py-2 text-xs text-center text-[var(--wraith-accent-blue)] rounded border border-[#30363d] hover:bg-[#30363d] transition-colors cursor-pointer"
                    @click.prevent="openLink('repo')"
                  >
                    Source Code
                  </a>
                </div>
                <!-- TODO: Wails binding — runtime.BrowserOpenURL(url) -->
              </div>
            </template>
          </div>
        </div>

        <!-- Footer -->
        <div class="flex items-center justify-end px-4 py-3 border-t border-[#30363d]">
          <button
            class="px-3 py-1.5 text-xs text-white bg-[#1f6feb] hover:bg-[#388bfd] rounded transition-colors cursor-pointer"
            @click="close"
          >
            Done
          </button>
        </div>
      </div>
    </div>
  </Teleport>
</template>

<script setup lang="ts">
import { ref, watch, onMounted } from "vue";
import { Call, Browser } from "@wailsio/runtime";

const SETTINGS = "github.com/vstockwell/wraith/internal/settings.SettingsService";
const UPDATER = "github.com/vstockwell/wraith/internal/updater.UpdateService";

type Section = "general" | "terminal" | "vault" | "about";

const visible = ref(false);
const activeSection = ref<Section>("general");

const sections = [
  {
    id: "general" as const,
    label: "General",
    icon: `<svg viewBox="0 0 16 16" fill="currentColor" class="w-3.5 h-3.5"><path d="M8 0a8.2 8.2 0 0 1 .701.031C8.955.017 9.209 0 9.466 0a1.934 1.934 0 0 1 1.466.665c.33.367.51.831.54 1.316a7.96 7.96 0 0 1 .82.4c.463-.207.97-.29 1.476-.19.504.1.963.37 1.3.77.339.404.516.91.5 1.423a1.94 1.94 0 0 1-.405 1.168 8.02 8.02 0 0 1 .356.9 1.939 1.939 0 0 1 1.48.803 1.941 1.941 0 0 1 0 2.29 1.939 1.939 0 0 1-1.48.803c-.095.316-.215.622-.357.9a1.94 1.94 0 0 1-.094 2.59 1.94 1.94 0 0 1-2.776.22 7.96 7.96 0 0 1-.82.4 1.94 1.94 0 0 1-2.006 1.98A8.2 8.2 0 0 1 8 16a8.2 8.2 0 0 1-.701-.031 1.938 1.938 0 0 1-2.005-1.98 7.96 7.96 0 0 1-.82-.4 1.94 1.94 0 0 1-2.776-.22 1.94 1.94 0 0 1-.094-2.59 8.02 8.02 0 0 1-.357-.9A1.939 1.939 0 0 1 0 8.945a1.941 1.941 0 0 1 0-2.29 1.939 1.939 0 0 1 1.247-.803c.095-.316.215-.622.357-.9a1.94 1.94 0 0 1 .094-2.59 1.94 1.94 0 0 1 2.776-.22c.258-.157.532-.293.82-.4A1.934 1.934 0 0 1 6.834.665 1.934 1.934 0 0 1 8.3.03 8.2 8.2 0 0 1 8 0ZM8 5a3 3 0 1 0 0 6 3 3 0 0 0 0-6Z"/></svg>`,
  },
  {
    id: "terminal" as const,
    label: "Terminal",
    icon: `<svg viewBox="0 0 16 16" fill="currentColor" class="w-3.5 h-3.5"><path d="M0 2.75C0 1.784.784 1 1.75 1h12.5c.966 0 1.75.784 1.75 1.75v10.5A1.75 1.75 0 0 1 14.25 15H1.75A1.75 1.75 0 0 1 0 13.25Zm1.75-.25a.25.25 0 0 0-.25.25v10.5c0 .138.112.25.25.25h12.5a.25.25 0 0 0 .25-.25V2.75a.25.25 0 0 0-.25-.25ZM7.25 8a.749.749 0 0 1-.22.53l-2.25 2.25a.749.749 0 1 1-1.06-1.06L5.44 8 3.72 6.28a.749.749 0 1 1 1.06-1.06l2.25 2.25c.141.14.22.331.22.53Zm1.5 1.5h3a.75.75 0 0 1 0 1.5h-3a.75.75 0 0 1 0-1.5Z"/></svg>`,
  },
  {
    id: "vault" as const,
    label: "Vault",
    icon: `<svg viewBox="0 0 16 16" fill="currentColor" class="w-3.5 h-3.5"><path d="M4 4v2h-.25A1.75 1.75 0 0 0 2 7.75v5.5c0 .966.784 1.75 1.75 1.75h8.5A1.75 1.75 0 0 0 14 13.25v-5.5A1.75 1.75 0 0 0 12.25 6H12V4a4 4 0 1 0-8 0Zm6.5 2V4a2.5 2.5 0 0 0-5 0v2ZM8 9.5a1.5 1.5 0 0 1 .5 2.915V13.5a.5.5 0 0 1-1 0v-1.085A1.5 1.5 0 0 1 8 9.5Z"/></svg>`,
  },
  {
    id: "about" as const,
    label: "About",
    icon: `<svg viewBox="0 0 16 16" fill="currentColor" class="w-3.5 h-3.5"><path d="M0 8a8 8 0 1 1 16 0A8 8 0 0 1 0 8Zm8-6.5a6.5 6.5 0 1 0 0 13 6.5 6.5 0 0 0 0-13ZM6.5 7.75A.75.75 0 0 1 7.25 7h1a.75.75 0 0 1 .75.75v2.75h.25a.75.75 0 0 1 0 1.5h-2a.75.75 0 0 1 0-1.5h.25v-2h-.25a.75.75 0 0 1-.75-.75ZM8 6a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z"/></svg>`,
  },
];

const themeNames = [
  "Dracula",
  "Nord",
  "Monokai",
  "One Dark",
  "Solarized Dark",
  "Gruvbox Dark",
  "MobaXTerm Classic",
];

const settings = ref({
  defaultProtocol: "ssh" as "ssh" | "rdp",
  sidebarWidth: 240,
  terminalTheme: "Dracula",
  fontSize: 14,
  scrollbackBuffer: 5000,
});

/** Load saved settings from Go backend on mount. */
onMounted(async () => {
  try {
    const [protocol, sidebarW, theme, fontSize, scrollback] = await Promise.all([
      Call.ByName(`${SETTINGS}.Get`, "default_protocol") as Promise<string>,
      Call.ByName(`${SETTINGS}.Get`, "sidebar_width") as Promise<string>,
      Call.ByName(`${SETTINGS}.Get`, "terminal_theme") as Promise<string>,
      Call.ByName(`${SETTINGS}.Get`, "font_size") as Promise<string>,
      Call.ByName(`${SETTINGS}.Get`, "scrollback_buffer") as Promise<string>,
    ]);
    if (protocol) settings.value.defaultProtocol = protocol as "ssh" | "rdp";
    if (sidebarW) settings.value.sidebarWidth = Number(sidebarW);
    if (theme) settings.value.terminalTheme = theme;
    if (fontSize) settings.value.fontSize = Number(fontSize);
    if (scrollback) settings.value.scrollbackBuffer = Number(scrollback);
    // Load version from Go backend
    const ver = await Call.ByName(`${APP}.GetVersion`) as string;
    if (ver) currentVersion.value = ver;
  } catch (err) {
    console.error("Failed to load settings:", err);
  }
});

/** Persist settings changes to Go backend as they change. */
watch(() => settings.value.defaultProtocol, (val) => {
  Call.ByName(`${SETTINGS}.Set`, "default_protocol", val).catch(console.error);
});
watch(() => settings.value.sidebarWidth, (val) => {
  Call.ByName(`${SETTINGS}.Set`, "sidebar_width", String(val)).catch(console.error);
});
watch(() => settings.value.terminalTheme, (val) => {
  Call.ByName(`${SETTINGS}.Set`, "terminal_theme", val).catch(console.error);
});
watch(() => settings.value.fontSize, (val) => {
  Call.ByName(`${SETTINGS}.Set`, "font_size", String(val)).catch(console.error);
});
watch(() => settings.value.scrollbackBuffer, (val) => {
  Call.ByName(`${SETTINGS}.Set`, "scrollback_buffer", String(val)).catch(console.error);
});

// --- Update check state ---
type UpdateCheckState = "idle" | "checking" | "found" | "downloading" | "up-to-date" | "error";
const updateCheckState = ref<UpdateCheckState>("idle");
const APP = "github.com/vstockwell/wraith/internal/app.WraithApp";
const currentVersion = ref("loading...");
const latestVersion = ref("");
const updateInfo = ref<{ available: boolean; currentVersion: string; latestVersion: string; downloadUrl: string; sha256: string } | null>(null);

function open(): void {
  visible.value = true;
  activeSection.value = "general";
}

function close(): void {
  visible.value = false;
}

async function changeMasterPassword(): Promise<void> {
  const oldPw = prompt("Current master password:");
  if (!oldPw) return;
  const newPw = prompt("New master password:");
  if (!newPw) return;
  const confirmPw = prompt("Confirm new master password:");
  if (newPw !== confirmPw) {
    alert("Passwords do not match.");
    return;
  }
  try {
    const APP = "github.com/vstockwell/wraith/internal/app.WraithApp";
    // Verify old password by unlocking, then create new vault
    await Call.ByName(`${APP}.Unlock`, oldPw);
    await Call.ByName(`${APP}.CreateVault`, newPw);
    alert("Master password changed successfully.");
  } catch (err) {
    alert(`Failed to change password: ${err}`);
  }
}

function exportVault(): void {
  // Not implemented yet — needs Go method to export encrypted DB
  alert("Export vault is not yet available. Your data is stored in %APPDATA%\\Wraith\\wraith.db");
}

function importVault(): void {
  // Not implemented yet — needs Go method to import encrypted DB
  alert("Import vault is not yet available. Copy wraith.db to %APPDATA%\\Wraith\\ to restore.");
}

async function checkForUpdates(): Promise<void> {
  if (updateCheckState.value === "checking") return;

  if (updateCheckState.value === "found" && updateInfo.value) {
    updateCheckState.value = "downloading";
    try {
      const path = await Call.ByName(`${UPDATER}.DownloadUpdate`, updateInfo.value) as string;
      await Call.ByName(`${UPDATER}.ApplyUpdate`, path);
    } catch (err) {
      console.error("Update failed:", err);
      updateCheckState.value = "found";
    }
    return;
  }

  updateCheckState.value = "checking";
  try {
    const info = await Call.ByName(`${UPDATER}.CheckForUpdate`) as {
      available: boolean;
      currentVersion: string;
      latestVersion: string;
      downloadUrl: string;
      sha256: string;
    };
    currentVersion.value = info.currentVersion || currentVersion.value;
    if (info.available) {
      latestVersion.value = info.latestVersion;
      updateInfo.value = info;
      updateCheckState.value = "found";
    } else {
      updateCheckState.value = "up-to-date";
    }
  } catch {
    updateCheckState.value = "error";
  }
}

function openLink(target: string): void {
  const urls: Record<string, string> = {
    docs: "https://github.com/wraith/docs",
    repo: "https://github.com/wraith",
  };
  const url = urls[target] ?? target;
  Browser.OpenURL(url).catch(console.error);
}

defineExpose({ open, close, visible });
</script>
