<script setup lang="ts">
import { computed, onMounted, reactive, ref, watch } from "vue";
import { apiDelete, apiGet, apiPost, apiPut } from "../api";
import FormStatus from "../components/FormStatus.vue";
import PageHeader from "../components/PageHeader.vue";
import SearchSelect from "../components/SearchSelect.vue";
import { reserveNextNumber } from "../number-ranges";
import { liveUpdateState } from "../realtime";
import type { Customer, Item, Quote, QuoteItem } from "../types";

const emptyItem = (): QuoteItem => ({ item_id: "", description: "", quantity: "1", unit_price: "0", original_unit_price: null, discount_percent: "0", tax_rate: "19" });
const emptyForm = () => ({ quote_number: "", customer_id: "", status: "draft", valid_until: null as string | null, cash_discount_term_id: null as string | null, customer_discount_percent: "0", notes: "", items: [emptyItem()] });

const quotes = ref<Quote[]>([]);
const customers = ref<Customer[]>([]);
const items = ref<Item[]>([]);
const selectedId = ref<string | null>(null);
const form = reactive(emptyForm());
const status = ref("");
const kind = ref<"info" | "success" | "error">("info");
const selectedQuote = computed(() => quotes.value.find((quote) => quote.id === selectedId.value));
const search = ref("");
const customerName = (customerId: string) => customers.value.find((customer) => customer.id === customerId)?.name ?? customerId;
const filteredQuotes = computed(() => {
  const needle = search.value.trim().toLowerCase();
  if (!needle) return quotes.value;
  return quotes.value.filter((quote) =>
    `${quote.quote_number} ${customerName(quote.customer_id)} ${quote.status}`.toLowerCase().includes(needle)
  );
});

async function load() {
  const [quoteResult, customerResult, itemResult] = await Promise.all([
    apiGet<Quote[]>("/api/v1/quotes"),
    apiGet<Customer[]>("/api/v1/customers"),
    apiGet<Item[]>("/api/v1/items")
  ]);
  if (quoteResult.ok) quotes.value = quoteResult.data; else { status.value = quoteResult.message; kind.value = "error"; }
  if (customerResult.ok) customers.value = customerResult.data.filter((customer) => customer.status === "active");
  if (itemResult.ok) items.value = itemResult.data.filter((item) => item.status === "active");
}

async function createNew() {
  selectedId.value = null;
  Object.assign(form, emptyForm());
  form.quote_number = (await reserveNextNumber("quotes")) ?? "";
}

function select(quote: Quote) {
  selectedId.value = quote.id;
  Object.assign(form, { ...quote, items: quote.items.map((item) => ({ ...item })) });
}

function addLine() {
  form.items.push(emptyItem());
}

function removeLine(index: number) {
  if (form.items.length > 1) form.items.splice(index, 1);
}

function applyItemDefaults(line: QuoteItem) {
  const item = items.value.find((record) => record.id === line.item_id);
  if (!item) return;
  line.description = item.name;
  line.unit_price = item.default_sales_price ?? "0";
  line.original_unit_price = item.default_sales_price ?? null;
  line.tax_rate = item.tax_rate;
}

async function save() {
  const result = selectedId.value
    ? await apiPut<Quote>(`/api/v1/quotes/${selectedId.value}`, form)
    : await apiPost<Quote>("/api/v1/quotes", form);
  status.value = result.ok ? "Angebot gespeichert." : result.message;
  kind.value = result.ok ? "success" : "error";
  if (result.ok) { selectedId.value = result.data.id; await load(); }
}

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

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

<template>
  <PageHeader title="Angebote" description="Angebote mit festen Artikelpositionen und individuellen Preisen." />
  <div class="workspace-split">
    <section class="panel list-panel">
      <div class="section-title"><h2>Angebote</h2><button type="button" @click="createNew">Neu</button></div>
      <label class="field list-search"><span>Suche</span><input v-model="search" type="search" placeholder="Angebotsnummer, Kunde oder Status" /></label>
      <button v-for="quote in filteredQuotes" :key="quote.id" type="button" class="list-row" :class="{ selected: selectedId === quote.id }" @click="select(quote)">
        <strong>{{ quote.quote_number }}</strong>
        <span>{{ customerName(quote.customer_id) }}</span>
        <small>{{ quote.status }}</small>
      </button>
      <p v-if="quotes.length === 0" class="empty">Keine Angebote vorhanden.</p>
      <p v-else-if="filteredQuotes.length === 0" class="empty">Keine Treffer.</p>
    </section>
    <section class="panel detail-panel">
      <form @submit.prevent="save">
        <div class="form-grid">
          <label class="field"><span>Angebotsnummer</span><div class="readonly-value">{{ form.quote_number || "wird automatisch vergeben" }}</div></label>
          <label class="field"><span>Kunde</span><SearchSelect v-model="form.customer_id" :options="customers.map((customer) => ({ id: customer.id, number: customer.customer_number, name: customer.name }))" placeholder="Kunden-Nr. oder Name suchen" required /></label>
          <label class="field"><span>Status</span><select v-model="form.status"><option value="draft">Entwurf</option><option value="sent">Gesendet</option><option value="accepted">Angenommen</option><option value="rejected">Abgelehnt</option><option value="expired">Abgelaufen</option><option value="cancelled">Storniert</option></select></label>
          <label class="field"><span>Gültig bis</span><input v-model="form.valid_until" type="date" /></label>
          <label class="field"><span>Kundenrabatt %</span><input v-model="form.customer_discount_percent" type="number" min="0" max="100" step="0.01" /></label>
          <label class="field full-width"><span>Notizen</span><textarea v-model="form.notes" rows="3" /></label>
        </div>
        <div class="sub-panel">
          <div class="section-title"><h2>Positionen</h2><button type="button" @click="addLine">Position</button></div>
          <div v-for="(line, index) in form.items" :key="index" class="quote-line">
            <label class="field full-width"><span>Artikel</span><SearchSelect v-model="line.item_id" :options="items.map((item) => ({ id: item.id, number: item.item_number, name: item.name }))" placeholder="Artikel-Nr. oder Name suchen" required @change="applyItemDefaults(line)" /></label>
            <label class="field"><span>Menge</span><input v-model="line.quantity" type="number" min="0.0001" step="0.01" required /></label>
            <label class="field"><span>Preis</span><input v-model="line.unit_price" type="number" min="0" step="0.01" required /></label>
            <label class="field"><span>Rabatt %</span><input v-model="line.discount_percent" type="number" min="0" max="100" step="0.01" /></label>
            <label class="field"><span>Steuer %</span><input v-model="line.tax_rate" type="number" min="0" step="0.01" /></label>
            <label class="field full-width"><span>Beschreibung</span><input v-model="line.description" /></label>
            <button type="button" class="secondary" @click="removeLine(index)">Entfernen</button>
          </div>
        </div>
        <div class="form-actions"><button type="submit">Speichern</button><button v-if="selectedQuote" type="button" class="secondary" @click="cancelQuote">Stornieren</button></div>
        <FormStatus :message="status" :kind="kind" />
      </form>
    </section>
  </div>
</template>
