<template>
  <div class="p-6 max-w-2xl mx-auto">
    <div class="mb-6">
      <h1 class="text-text-primary text-xl font-semibold mb-1">Settings</h1>
      <p class="text-text-dim text-sm">
        Turnstone preferences — stored alongside the log database.
      </p>
    </div>

    <div class="rounded border border-surface-border bg-surface-raised p-5 space-y-6">
      <!-- Entry point -->
      <div>
        <h2 id="entry-point-label" class="text-text-primary text-sm font-semibold mb-1">Quick Capture Entry Point</h2>
        <p class="text-text-dim text-xs mb-3">
          Where the "describe it and search" input appears on every page.
        </p>
        <div role="radiogroup" aria-labelledby="entry-point-label" class="flex gap-3">
          <button
            v-for="(opt, idx) in entryPointOptions"
            :key="opt.value"
            :ref="(el) => collectEntryRef(el, idx)"
            role="radio"
            :aria-checked="prefs.entry_point_style === opt.value"
            :tabindex="prefs.entry_point_style === opt.value ? 0 : -1"
            @click="setEntryPoint(opt.value as 'topbar' | 'fab')"
            @keydown="handleEntryPointKey($event, idx)"
            :class="[
              'flex-1 px-4 py-3 rounded border text-sm transition-colors text-left',
              prefs.entry_point_style === opt.value
                ? 'border-accent bg-accent/10 text-accent'
                : 'border-surface-border text-text-muted hover:text-text-primary hover:border-accent'
            ]"
          >
            <div class="font-medium">{{ opt.label }}</div>
            <div class="text-xs text-text-dim mt-0.5">{{ opt.desc }}</div>
          </button>
        </div>
      </div>

      <!-- LLM config -->
      <div>
        <h2 class="text-text-primary text-sm font-semibold mb-1">LLM Reasoning</h2>
        <p class="text-text-dim text-xs mb-3">
          LLM endpoint for plain-language diagnoses. Works with local Ollama or a remote
          cf-orch coordinator (e.g. <span class="font-mono">https://orch.circuitforge.tech</span>).
          Leave blank to disable.
        </p>
        <div class="space-y-3">
          <div>
            <label class="block text-xs text-text-dim mb-1">LLM Endpoint URL</label>
            <input
              v-model="prefs.llm_url"
              type="text"
              placeholder="http://localhost:11434"
              class="w-full bg-surface border border-surface-border rounded px-3 py-2 text-sm text-text-primary placeholder-text-dim focus:outline-none focus:border-accent transition-colors"
            />
          </div>
          <div>
            <label class="block text-xs text-text-dim mb-1">Model</label>
            <input
              v-model="prefs.llm_model"
              type="text"
              placeholder="llama3.1:8b"
              class="w-full bg-surface border border-surface-border rounded px-3 py-2 text-sm text-text-primary placeholder-text-dim focus:outline-none focus:border-accent transition-colors"
            />
          </div>
          <div>
            <label class="block text-xs text-text-dim mb-1">
              API Key
              <span class="text-text-dim font-normal">(optional — required for cf-orch remote inference)</span>
            </label>
            <div class="relative">
              <input
                v-model="prefs.llm_api_key"
                :type="showApiKey ? 'text' : 'password'"
                placeholder="Leave blank for local Ollama"
                class="w-full bg-surface border border-surface-border rounded px-3 py-2 text-sm text-text-primary placeholder-text-dim focus:outline-none focus:border-accent transition-colors"
              />
              <button
                type="button"
                @click="showApiKey = !showApiKey"
                :aria-label="showApiKey ? 'Hide API key' : 'Show API key'"
                class="absolute right-3 top-1/2 -translate-y-1/2 text-text-dim hover:text-text-primary text-xs"
              >{{ showApiKey ? 'Hide' : 'Show' }}</button>
            </div>
          </div>
          <button
            @click="saveLlm"
            class="px-4 py-2 bg-accent text-surface text-sm rounded font-medium hover:opacity-90 transition-opacity"
          >
            Save LLM settings
          </button>
        </div>
      </div>

      <!-- Severity overrides -->
      <div>
        <h2 class="text-text-primary text-sm font-semibold mb-1">Severity Overrides</h2>
        <p class="text-text-dim text-xs mb-3">
          Regex rules applied at query time — entries that match are shown at the overridden severity on the dashboard. DB values are unchanged.
        </p>

        <div class="space-y-2 mb-3">
          <div
            v-for="(rule, i) in prefs.severity_overrides"
            :key="i"
            class="flex items-start gap-3 rounded border border-surface-border bg-surface p-3"
          >
            <button
              role="switch"
              :aria-checked="rule.enabled"
              :aria-label="`${rule.name || 'Override'} rule enabled`"
              @click="toggleOverride(i)"
              :class="[
                'mt-0.5 w-9 h-5 rounded-full flex-shrink-0 transition-colors relative',
                rule.enabled ? 'bg-accent' : 'bg-surface-border'
              ]"
              :title="rule.enabled ? 'Enabled — click to disable' : 'Disabled — click to enable'"
            >
              <span :class="['absolute top-0.5 w-4 h-4 rounded-full bg-white shadow transition-transform', rule.enabled ? 'translate-x-4' : 'translate-x-0.5']"></span>
            </button>
            <div class="flex-1 min-w-0">
              <div class="flex items-center gap-2 flex-wrap">
                <span class="text-sm text-text-primary font-medium">{{ rule.name }}</span>
                <span class="text-xs px-1.5 py-0.5 rounded bg-surface-border text-text-dim">→ {{ rule.override_severity }}</span>
              </div>
              <p class="text-xs text-text-dim font-mono mt-0.5 truncate">{{ rule.pattern }}</p>
            </div>
            <button
              @click="deleteOverride(i)"
              :aria-label="`Delete override rule: ${rule.name || 'unnamed'}`"
              class="text-text-dim hover:text-sev-error text-xs flex-shrink-0 mt-0.5"
              title="Delete rule"
            >✕</button>
          </div>
          <p v-if="!prefs.severity_overrides?.length" class="text-text-dim text-xs">No rules configured.</p>
        </div>

        <!-- Add rule form -->
        <div v-if="!showAddOverride">
          <button
            @click="showAddOverride = true"
            class="text-accent text-xs hover:underline"
          >+ Add override rule</button>
        </div>
        <div v-else class="rounded border border-surface-border bg-surface p-3 space-y-2">
          <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
            <div>
              <label class="block text-xs text-text-dim mb-1">Name</label>
              <input v-model="newRule.name" type="text" placeholder="e.g. PAM auth noise"
                class="w-full bg-surface-raised border border-surface-border rounded px-2 py-1.5 text-sm text-text-primary placeholder-text-dim focus:outline-none focus:border-accent" />
            </div>
            <div>
              <label class="block text-xs text-text-dim mb-1">Override severity</label>
              <select v-model="newRule.override_severity"
                class="w-full bg-surface-raised border border-surface-border rounded px-2 py-1.5 text-sm text-text-primary focus:outline-none focus:border-accent">
                <option>WARN</option>
                <option>INFO</option>
                <option>DEBUG</option>
              </select>
            </div>
          </div>
          <div>
            <label class="block text-xs text-text-dim mb-1">Pattern (regex)</label>
            <input v-model="newRule.pattern" type="text" placeholder="e.g. pam_unix.*auth"
              class="w-full bg-surface-raised border border-surface-border rounded px-2 py-1.5 text-sm font-mono text-text-primary placeholder-text-dim focus:outline-none focus:border-accent" />
          </div>
          <div class="flex gap-2">
            <button @click="addOverride"
              class="px-3 py-1.5 bg-accent text-surface text-xs rounded font-medium hover:opacity-90 transition-opacity">
              Add
            </button>
            <button @click="showAddOverride = false" class="text-text-dim hover:text-text-primary text-xs">Cancel</button>
          </div>
        </div>
      </div>

      <p
        v-if="saveStatus"
        role="status"
        aria-live="polite"
        class="text-xs"
        :class="saveStatus.ok ? 'text-green-400' : 'text-sev-error'"
      >
        {{ saveStatus.msg }}
      </p>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue'
import type { ComponentPublicInstance } from 'vue'

const BASE = import.meta.env.BASE_URL.replace(/\/$/, '')

interface SeverityOverride {
  name: string
  pattern: string
  override_severity: string
  enabled: boolean
}

interface Prefs {
  entry_point_style: 'topbar' | 'fab'
  llm_url: string
  llm_model: string
  llm_api_key: string
  severity_overrides: SeverityOverride[]
}

const prefs      = ref<Prefs>({ entry_point_style: 'topbar', llm_url: '', llm_model: '', llm_api_key: '', severity_overrides: [] })
const saveStatus = ref<{ ok: boolean; msg: string } | null>(null)
const showAddOverride = ref(false)
const showApiKey = ref(false)
const newRule = ref<SeverityOverride>({ name: '', pattern: '', override_severity: 'WARN', enabled: true })
const entryPointBtnRefs = ref<HTMLButtonElement[]>([])

const entryPointOptions = [
  { value: 'topbar', label: 'Top bar',  desc: 'Persistent input bar below the nav on every page' },
  { value: 'fab',    label: 'FAB',      desc: 'Floating action button in the bottom-right corner' },
]

function collectEntryRef(el: any, idx: number) {
  if (el instanceof HTMLButtonElement) entryPointBtnRefs.value[idx] = el
}

function handleEntryPointKey(e: KeyboardEvent, idx: number) {
  let next = idx
  if (e.key === 'ArrowRight' || e.key === 'ArrowDown') next = idx + 1
  else if (e.key === 'ArrowLeft' || e.key === 'ArrowUp') next = idx - 1
  else return
  e.preventDefault()
  const clamped = Math.max(0, Math.min(entryPointOptions.length - 1, next))
  setEntryPoint(entryPointOptions[clamped]!.value as 'topbar' | 'fab')
  const nextBtn = entryPointBtnRefs.value[clamped]
  if (nextBtn) nextBtn.focus()
}

onMounted(async () => {
  try {
    const res = await fetch(`${BASE}/api/settings`)
    if (res.ok) prefs.value = await res.json()
  } catch { /* non-critical — defaults stay */ }
})

async function patch(body: Partial<Prefs>) {
  const res = await fetch(`${BASE}/api/settings`, {
    method: 'PATCH',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify(body),
  })
  if (!res.ok) throw new Error(await res.text())
  prefs.value = await res.json()
}

async function setEntryPoint(style: 'topbar' | 'fab') {
  saveStatus.value = null
  try {
    await patch({ entry_point_style: style })
    saveStatus.value = { ok: true, msg: 'Saved' }
    setTimeout(() => { saveStatus.value = null }, 2000)
  } catch {
    saveStatus.value = { ok: false, msg: 'Save failed — check server connection' }
  }
}

async function saveLlm() {
  saveStatus.value = null
  try {
    await patch({ llm_url: prefs.value.llm_url, llm_model: prefs.value.llm_model, llm_api_key: prefs.value.llm_api_key })
    saveStatus.value = { ok: true, msg: 'LLM settings saved' }
    setTimeout(() => { saveStatus.value = null }, 2000)
  } catch {
    saveStatus.value = { ok: false, msg: 'Save failed — check server connection' }
  }
}

async function saveOverrides() {
  try {
    await patch({ severity_overrides: prefs.value.severity_overrides })
    saveStatus.value = { ok: true, msg: 'Overrides saved' }
    setTimeout(() => { saveStatus.value = null }, 2000)
  } catch {
    saveStatus.value = { ok: false, msg: 'Save failed — check server connection' }
  }
}

async function toggleOverride(i: number) {
  const rule = prefs.value.severity_overrides[i]
  if (rule) rule.enabled = !rule.enabled
  await saveOverrides()
}

async function deleteOverride(i: number) {
  prefs.value.severity_overrides.splice(i, 1)
  await saveOverrides()
}

async function addOverride() {
  if (!newRule.value.name.trim() || !newRule.value.pattern.trim()) return
  prefs.value.severity_overrides.push({ ...newRule.value })
  newRule.value = { name: '', pattern: '', override_severity: 'WARN', enabled: true }
  showAddOverride.value = false
  await saveOverrides()
}
</script>
