<script setup lang="ts">
import { onMounted, reactive, ref, watch } from "vue";
import { apiDelete, apiGet, apiPost } from "../api";
import FormStatus from "../components/FormStatus.vue";
import PageHeader from "../components/PageHeader.vue";
import { liveUpdateState } from "../realtime";
import type { DocumentAuditLogEntry, DocumentDownload, DocumentRecord, EntityLink } from "../types";

const documents = ref<DocumentRecord[]>([]);
const auditLog = ref<DocumentAuditLogEntry[]>([]);
const selectedId = ref<string | null>(null);
const form = reactive({ title: "", description: "", file_name: "", content_type: "text/plain", content_base64: "", links: [] as EntityLink[] });
const linkType = ref("customer");
const linkId = ref("");
const status = ref("");
const kind = ref<"info" | "success" | "error">("info");

async function load() {
  const result = await apiGet<DocumentRecord[]>("/api/v1/documents");
  if (result.ok) documents.value = result.data;
  else { status.value = result.message; kind.value = "error"; }
}

function createNew() {
  selectedId.value = null;
  Object.assign(form, { title: "", description: "", file_name: "", content_type: "text/plain", content_base64: "", links: [] });
  auditLog.value = [];
}

async function select(record: DocumentRecord) {
  selectedId.value = record.id;
  Object.assign(form, {
    title: record.title,
    description: record.description,
    file_name: record.latest_version?.file_name ?? "",
    content_type: record.latest_version?.content_type ?? "text/plain",
    content_base64: "",
    links: [...record.links]
  });
  await loadAuditLog(record.id);
}

async function onFileChange(event: Event) {
  const file = (event.target as HTMLInputElement).files?.[0];
  if (!file) return;
  form.file_name = file.name;
  form.content_type = file.type || "application/octet-stream";
  const buffer = await file.arrayBuffer();
  const bytes = new Uint8Array(buffer);
  let binary = "";
  for (const byte of bytes) binary += String.fromCharCode(byte);
  form.content_base64 = btoa(binary);
}

function addLink() {
  if (!linkId.value.trim()) return;
  form.links.push({ entity_type: linkType.value, entity_id: linkId.value.trim() });
  linkId.value = "";
}

function removeLink(index: number) {
  form.links.splice(index, 1);
}

async function upload() {
  const result = await apiPost<DocumentRecord>("/api/v1/documents", form);
  status.value = result.ok ? "Dokument hochgeladen." : result.message;
  kind.value = result.ok ? "success" : "error";
  if (result.ok) { selectedId.value = result.data.id; await load(); await loadAuditLog(result.data.id); }
}

async function download() {
  if (!selectedId.value) return;
  const result = await apiGet<DocumentDownload>(`/api/v1/documents/${selectedId.value}/download`);
  if (!result.ok) { status.value = result.message; kind.value = "error"; return; }
  const bytes = Uint8Array.from(atob(result.data.content_base64), (char) => char.charCodeAt(0));
  const blob = new Blob([bytes], { type: result.data.content_type });
  const url = URL.createObjectURL(blob);
  const link = document.createElement("a");
  link.href = url;
  link.download = result.data.file_name;
  link.click();
  URL.revokeObjectURL(url);
  status.value = "Download vorbereitet.";
  kind.value = "success";
  await loadAuditLog(selectedId.value);
}

async function archiveDocument() {
  if (!selectedId.value) return;
  const result = await apiDelete(`/api/v1/documents/${selectedId.value}`);
  status.value = result.ok ? "Dokument archiviert." : result.message;
  kind.value = result.ok ? "success" : "error";
  if (result.ok) await load();
}

async function loadAuditLog(documentId: string) {
  const result = await apiGet<DocumentAuditLogEntry[]>(`/api/v1/documents/${documentId}/audit-log`);
  if (result.ok) auditLog.value = result.data;
}

onMounted(load);
watch(() => liveUpdateState.revision, load);
</script>

<template>
  <PageHeader title="Dokumente" description="Dokumente verschlüsselt ablegen, zuordnen und herunterladen." />
  <div class="workspace-split">
    <section class="panel list-panel">
      <div class="section-title"><h2>Dokumente</h2><button type="button" @click="createNew">Neu</button></div>
      <button v-for="record in documents" :key="record.id" type="button" class="list-row" :class="{ selected: selectedId === record.id }" @click="select(record)">
        <strong>{{ record.title }}</strong>
        <span>{{ record.latest_version?.file_name ?? "ohne Datei" }}</span>
        <small>{{ record.status }}</small>
      </button>
      <p v-if="documents.length === 0" class="empty">Keine Dokumente vorhanden.</p>
    </section>
    <section class="panel detail-panel">
      <form @submit.prevent="upload">
        <div class="form-grid">
          <label class="field"><span>Titel</span><input v-model="form.title" required /></label>
          <label class="field"><span>Content-Type</span><input v-model="form.content_type" required /></label>
          <label class="field full-width"><span>Beschreibung</span><textarea v-model="form.description" rows="4" /></label>
          <label class="field full-width"><span>Datei</span><input type="file" @change="onFileChange" /></label>
          <label class="field full-width"><span>Dateiname</span><input v-model="form.file_name" required /></label>
        </div>
        <div class="sub-panel">
          <h2>Bezüge</h2>
          <div class="form-grid">
            <label class="field"><span>Typ</span><select v-model="linkType"><option value="customer">Kunde</option><option value="supplier">Lieferant</option><option value="activity">Aktivität</option><option value="communication">Kommunikation</option><option value="quote">Angebot</option><option value="outgoing_invoice">Ausgangsrechnung</option><option value="incoming_invoice">Eingangsrechnung</option><option value="item">Artikel</option></select></label>
            <label class="field"><span>ID</span><input v-model="linkId" /></label>
          </div>
          <button type="button" class="secondary" @click="addLink">Bezug hinzufügen</button>
          <div v-for="(link, index) in form.links" :key="`${link.entity_type}-${link.entity_id}`" class="data-row">
            <strong>{{ link.entity_type }}</strong><span>{{ link.entity_id }}</span><button type="button" class="secondary" @click="removeLink(index)">Entfernen</button>
          </div>
        </div>
        <div class="form-actions"><button type="submit">Hochladen</button><button v-if="selectedId" type="button" class="secondary" @click="download">Herunterladen</button><button v-if="selectedId" type="button" class="secondary" @click="archiveDocument">Archivieren</button></div>
        <FormStatus :message="status" :kind="kind" />
      </form>
      <div v-if="auditLog.length > 0" class="sub-panel">
        <h2>Audit-Log</h2>
        <div v-for="entry in auditLog" :key="entry.id" class="data-row"><strong>{{ entry.action }}</strong><span>{{ new Date(entry.created_at).toLocaleString("de-DE") }}</span><small>{{ entry.user_id ?? "-" }}</small></div>
      </div>
    </section>
  </div>
</template>
