<script setup lang="ts">
import { ref, computed } from "vue";
import { apiGet } from "@/api/client";
import DiffView from "@/components/DiffView.vue";
import type { DiffLine } from "@/composables/useAssist";

interface NoteVersion {
  id: number;
  note_id: number;
  title: string;
  tags: string[];
  body?: string;
  created_at: string;
}

const props = defineProps<{
  noteId: number;
  currentBody: string;
}>();

const emit = defineEmits<{
  (e: "restore", body: string, tags: string[]): void;
}>();

const expanded = ref(false);
const view = ref<"list" | "diff">("list");
const versions = ref<NoteVersion[]>([]);
const selectedVersion = ref<NoteVersion | null>(null);
const loading = ref(false);
const loadingDetail = ref(false);

const diff = computed<DiffLine[]>(() => {
  if (!selectedVersion.value?.body) return [];
  const aLines = props.currentBody.split("\n");
  const bLines = selectedVersion.value.body.split("\n");
  const m = aLines.length, n = bLines.length;
  const dp: number[][] = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
  for (let i = m - 1; i >= 0; i--)
    for (let j = n - 1; j >= 0; j--)
      dp[i][j] = aLines[i] === bLines[j]
        ? dp[i + 1][j + 1] + 1
        : Math.max(dp[i + 1][j], dp[i][j + 1]);
  const result: DiffLine[] = [];
  let i = 0, j = 0;
  while (i < m && j < n) {
    if (aLines[i] === bLines[j]) { result.push({ type: "equal", text: aLines[i++] }); j++; }
    else if (dp[i + 1][j] >= dp[i][j + 1]) result.push({ type: "delete", text: aLines[i++] });
    else result.push({ type: "insert", text: bLines[j++] });
  }
  while (i < m) result.push({ type: "delete", text: aLines[i++] });
  while (j < n) result.push({ type: "insert", text: bLines[j++] });
  return result;
});

function formatDate(iso: string): string {
  const d = new Date(iso);
  const now = new Date();
  const isToday = d.toDateString() === now.toDateString();
  if (isToday) {
    return d.toLocaleTimeString(undefined, { hour: "2-digit", minute: "2-digit" });
  }
  return d.toLocaleString(undefined, {
    month: "short", day: "numeric",
    hour: "2-digit", minute: "2-digit",
  });
}

async function toggle() {
  expanded.value = !expanded.value;
  if (expanded.value && versions.value.length === 0) {
    await loadVersions();
  }
}

async function loadVersions() {
  loading.value = true;
  try {
    const data = await apiGet<{ versions: NoteVersion[] }>(
      `/api/notes/${props.noteId}/versions`
    );
    versions.value = data.versions;
  } catch {
    // silent
  } finally {
    loading.value = false;
  }
}

async function selectVersion(v: NoteVersion) {
  if (v.body === undefined) {
    loadingDetail.value = true;
    try {
      const full = await apiGet<NoteVersion>(
        `/api/notes/${props.noteId}/versions/${v.id}`
      );
      const listItem = versions.value.find((x) => x.id === v.id);
      if (listItem) listItem.body = full.body;
      selectedVersion.value = full;
    } catch {
      // silent
    } finally {
      loadingDetail.value = false;
    }
  } else {
    selectedVersion.value = v;
  }
  view.value = "diff";
}

function back() {
  view.value = "list";
  selectedVersion.value = null;
}

function restore() {
  if (!selectedVersion.value?.body) return;
  emit("restore", selectedVersion.value.body, selectedVersion.value.tags ?? []);
  back();
}
</script>

<template>
  <div class="vh-section">
    <button class="vh-header" @click="toggle">
      <span class="vh-title">Version History</span>
      <span class="vh-chevron">{{ expanded ? "▴" : "▾" }}</span>
    </button>

    <div v-if="expanded" class="vh-body">

      <!-- List view -->
      <template v-if="view === 'list'">
        <div v-if="loading" class="vh-empty">Loading...</div>
        <div v-else-if="!versions.length" class="vh-empty">No snapshots yet.</div>
        <div
          v-for="v in versions"
          :key="v.id"
          class="vh-item"
          @click="selectVersion(v)"
        >
          {{ formatDate(v.created_at) }}
        </div>
      </template>

      <!-- Diff view -->
      <template v-else>
        <div class="vh-diff-actions">
          <button class="vh-btn-back" @click="back">← Back</button>
          <button
            class="vh-btn-restore"
            :disabled="!selectedVersion?.body"
            @click="restore"
          >Restore</button>
        </div>
        <div class="vh-diff-wrap">
          <div v-if="loadingDetail" class="vh-empty">Loading...</div>
          <DiffView v-else :diff="diff" />
        </div>
      </template>

    </div>
  </div>
</template>

<style scoped>
.vh-section {
  border-top: 1px solid var(--fs-border-color);
}

.vh-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  padding: 0.55rem 0.75rem;
  background: none;
  border: none;
  cursor: pointer;
  font-family: inherit;
  text-align: left;
}
.vh-header:hover { background: var(--fs-surface-raised); }

.vh-title {
  font-size: 0.75rem;
  font-weight: 700;
  color: var(--fs-text-secondary);
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.vh-chevron {
  font-size: 0.7rem;
  color: var(--fs-text-tertiary);
}

.vh-body {
  padding: 0 0 0.5rem;
}

.vh-empty {
  padding: 0.5rem 0.75rem;
  font-size: 0.8rem;
  color: var(--fs-text-tertiary);
}

.vh-item {
  padding: 0.35rem 0.75rem;
  font-size: 0.8rem;
  color: var(--fs-text-primary);
  cursor: pointer;
  font-family: monospace;
  border-left: 2px solid transparent;
}
.vh-item:hover {
  background: var(--fs-surface-raised);
  border-left-color: var(--fs-accent);
}

.vh-diff-actions {
  display: flex;
  gap: 0.4rem;
  padding: 0.4rem 0.75rem 0.35rem;
}

.vh-btn-back {
  background: none;
  border: 1px solid var(--fs-border-color);
  border-radius: var(--fs-radius-sm);
  padding: 0.25rem 0.6rem;
  font-size: 0.78rem;
  color: var(--fs-text-secondary);
  cursor: pointer;
  font-family: inherit;
}
.vh-btn-back:hover { border-color: var(--fs-accent); color: var(--fs-accent); }

.vh-btn-restore {
  background: var(--fs-action-primary);
  border: none;
  border-radius: var(--fs-radius-sm);
  padding: 0.25rem 0.6rem;
  font-size: 0.78rem;
  color: var(--fs-text-on-action);
  cursor: pointer;
  font-family: inherit;
}
.vh-btn-restore:disabled { opacity: 0.5; cursor: default; }

.vh-diff-wrap {
  padding: 0 0.5rem 0.25rem;
  max-height: 420px;
  overflow-y: auto;
  display: flex;
  flex-direction: column;
}
</style>
