<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from "vue";
import { storeToRefs } from "pinia";
import {
  Save,
  RotateCcw,
  RefreshCw,
  KeyRound,
  AlertTriangle,
  TerminalSquare,
} from "lucide-vue-next";
import { api } from "@/lib/api";
import { useConfigStore } from "@/stores/config";
import { useNodeStore } from "@/stores/node";

const configStore = useConfigStore();
const node = useNodeStore();
const { config } = storeToRefs(configStore);
const { phase, status } = storeToRefs(node);

// Local working copy for the form. We mirror the canonical config and
// synchronise on every write to the store.
const draft = reactive({
  peers: "",
  tunName: "",
  noTun: false,
});
const dirty = ref(false);

function loadDraft() {
  draft.peers = config.value.peers.join("\n");
  draft.tunName = config.value.tunName ?? "";
  draft.noTun = config.value.noTun;
  dirty.value = false;
}

watch(config, loadDraft, { immediate: true });

watch(
  draft,
  () => {
    dirty.value = true;
  },
  { deep: true },
);

async function save() {
  await configStore.save({
    peers: draft.peers
      .split(/\r?\n/)
      .map((s) => s.trim())
      .filter(Boolean),
    tunName: draft.tunName.trim() || null,
    noTun: draft.noTun,
  });
  dirty.value = false;
}

async function reset() {
  if (!confirm("Restore default daemon configuration?")) return;
  await configStore.reset();
}

// ─── Identity ───────────────────────────────────────────────────────────────

const regenBusy = ref(false);
const regenError = ref<string | null>(null);

async function regenerate() {
  if (
    !confirm(
      "Regenerate identity? This deletes the current private key. Your overlay IPv6 and public key will change. Anyone with peers configured by your old IP/key will have to update them.",
    )
  ) {
    return;
  }
  regenBusy.value = true;
  regenError.value = null;
  try {
    await api.regenerateIdentity();
  } catch (e) {
    regenError.value = String(e);
  } finally {
    regenBusy.value = false;
  }
}

// ─── Logs ───────────────────────────────────────────────────────────────────

const logs = ref<string[]>([]);
const logsLoading = ref(false);

async function refreshLogs() {
  logsLoading.value = true;
  try {
    logs.value = await api.sidecarLogs();
  } finally {
    logsLoading.value = false;
  }
}

const isReady = computed(() => phase.value === "ready");

onMounted(async () => {
  if (isReady.value) await refreshLogs();
});
</script>

<template>
  <div class="grid gap-4 lg:grid-cols-2">
    <!-- Daemon configuration ───────────────────────────────────────────── -->
    <section class="rounded-lg border border-border bg-card">
      <header class="border-b border-border px-4 py-3">
        <h2 class="text-sm font-medium">Daemon configuration</h2>
        <p class="mt-0.5 text-xs text-muted-foreground">
          Applied next time the daemon starts. Currently running daemon
          isn't reconfigured live.
        </p>
      </header>
      <div class="space-y-4 px-4 py-4">
        <div>
          <label class="text-xs uppercase tracking-wide text-muted-foreground">
            Static peers (one per line)
          </label>
          <textarea
            v-model="draft.peers"
            rows="6"
            spellcheck="false"
            class="mt-1 w-full resize-y rounded-md border border-input bg-background px-3 py-2 font-mono text-xs focus:outline-none focus:ring-2 focus:ring-ring"
            placeholder="tcp://188.40.132.242:9651"
          />
        </div>
        <div class="flex items-center gap-3">
          <input
            id="no-tun"
            v-model="draft.noTun"
            type="checkbox"
            class="h-4 w-4"
          />
          <label for="no-tun" class="text-sm">
            Disable TUN interface (<code class="font-mono text-xs">--no-tun</code>)
          </label>
        </div>
        <div>
          <label class="text-xs uppercase tracking-wide text-muted-foreground">
            TUN interface name (optional)
          </label>
          <input
            v-model="draft.tunName"
            type="text"
            class="mt-1 w-full rounded-md border border-input bg-background px-3 py-1.5 font-mono text-sm focus:outline-none focus:ring-2 focus:ring-ring"
            placeholder="mycelium0"
            :disabled="draft.noTun"
          />
        </div>
        <div class="flex justify-end gap-2 pt-2">
          <button
            class="inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1.5 text-xs hover:bg-secondary"
            @click="reset"
          >
            <RotateCcw class="h-3 w-3" />
            Defaults
          </button>
          <button
            class="inline-flex items-center gap-1.5 rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:opacity-90 disabled:opacity-50"
            :disabled="!dirty"
            @click="save"
          >
            <Save class="h-3 w-3" />
            Save
          </button>
        </div>
      </div>
    </section>

    <!-- Identity ───────────────────────────────────────────────────────── -->
    <section class="rounded-lg border border-border bg-card">
      <header class="border-b border-border px-4 py-3">
        <h2 class="flex items-center gap-2 text-sm font-medium">
          <KeyRound class="h-4 w-4" /> Identity
        </h2>
      </header>
      <div class="space-y-3 px-4 py-4 text-sm">
        <div>
          <div class="text-xs uppercase tracking-wide text-muted-foreground">
            Key file
          </div>
          <div class="mt-1 break-all font-mono text-xs">
            {{ status?.keyPath ?? "(unknown — start the daemon at least once)" }}
          </div>
        </div>
        <div class="rounded-md border border-destructive/30 bg-destructive/5 p-3 text-xs">
          <div class="flex items-start gap-2">
            <AlertTriangle class="mt-0.5 h-4 w-4 shrink-0 text-destructive" />
            <div class="space-y-2">
              <p>
                Regenerating discards your current private key, which means a
                new overlay IPv6 and public key. This is irreversible.
              </p>
              <button
                class="inline-flex items-center gap-1.5 rounded-md border border-destructive px-3 py-1 text-destructive hover:bg-destructive hover:text-destructive-foreground disabled:opacity-50"
                :disabled="regenBusy"
                @click="regenerate"
              >
                <RotateCcw class="h-3 w-3" />
                Regenerate identity
              </button>
              <p v-if="regenError" class="text-destructive">{{ regenError }}</p>
            </div>
          </div>
        </div>
      </div>
    </section>

    <!-- Logs ──────────────────────────────────────────────────────────── -->
    <section class="rounded-lg border border-border bg-card lg:col-span-2">
      <header class="flex items-center justify-between border-b border-border px-4 py-3">
        <h2 class="flex items-center gap-2 text-sm font-medium">
          <TerminalSquare class="h-4 w-4" /> Sidecar logs
        </h2>
        <button
          class="inline-flex items-center gap-1.5 rounded-md border border-border px-3 py-1 text-xs hover:bg-secondary disabled:opacity-50"
          :disabled="logsLoading"
          @click="refreshLogs"
        >
          <RefreshCw
            class="h-3 w-3"
            :class="logsLoading ? 'animate-spin' : ''"
          />
          Refresh
        </button>
      </header>
      <div
        class="max-h-72 overflow-y-auto bg-background px-4 py-2 font-mono text-[11px]"
      >
        <p v-if="!logs.length" class="py-4 text-center text-muted-foreground">
          No log entries — start the daemon to begin capturing.
        </p>
        <pre v-else class="whitespace-pre-wrap break-all">{{ logs.join("\n") }}</pre>
      </div>
    </section>

    <!-- About ────────────────────────────────────────────────────────── -->
    <section class="rounded-lg border border-border bg-card lg:col-span-2">
      <header class="border-b border-border px-4 py-3">
        <h2 class="text-sm font-medium">About</h2>
      </header>
      <dl class="grid grid-cols-1 gap-4 px-4 py-4 text-sm sm:grid-cols-3">
        <div>
          <dt class="text-xs uppercase tracking-wide text-muted-foreground">
            App
          </dt>
          <dd class="mt-1 font-mono text-xs">mycellium-ui 0.1.0</dd>
        </div>
        <div>
          <dt class="text-xs uppercase tracking-wide text-muted-foreground">
            Mycelium daemon
          </dt>
          <dd class="mt-1 font-mono text-xs">v0.6.1 (bundled)</dd>
        </div>
        <div>
          <dt class="text-xs uppercase tracking-wide text-muted-foreground">
            API endpoint
          </dt>
          <dd class="mt-1 font-mono text-xs">
            {{ status?.apiUrl ?? "—" }}
          </dd>
        </div>
      </dl>
    </section>
  </div>
</template>
