<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 { decimalString } from "../format";
import { matchesObjectSearch, reserveNextNumber } from "../number-ranges";
import { liveUpdateState } from "../realtime";
import type { CashDiscountTerm, Customer } from "../types";

const emptyCustomer = () => ({
  customer_number: "",
  name: "",
  status: "active",
  details: {
    street: "",
    postal_code: "",
    city: "",
    country: "Deutschland",
    email: "",
    phone: ""
  },
  standard_discount_percent: "0",
  cash_discount_term_id: null as string | null
});

const customers = ref<Customer[]>([]);
const cashDiscountTerms = ref<CashDiscountTerm[]>([]);
const selectedId = ref<string | null>(null);
const form = reactive(emptyCustomer());
const status = ref("");
const statusKind = ref<"info" | "success" | "error">("info");
const pending = ref(false);
const search = ref("");
const filteredCustomers = computed(() =>
  customers.value.filter((customer) => matchesObjectSearch(customer.customer_number, customer.name, search.value))
);

async function loadCustomers() {
  const result = await apiGet<Customer[]>("/api/v1/customers");
  if (!result.ok) {
    status.value = result.message;
    statusKind.value = "error";
    return;
  }
  customers.value = result.data;
}

async function loadCashDiscountTerms() {
  const result = await apiGet<CashDiscountTerm[]>("/api/v1/cash-discount-terms");
  if (result.ok) cashDiscountTerms.value = result.data.filter((term) => term.is_active);
}

async function newCustomer() {
  selectedId.value = null;
  Object.assign(form, emptyCustomer());
  form.details = { ...emptyCustomer().details };
  form.customer_number = (await reserveNextNumber("customers")) ?? "";
  status.value = "Neuer Kunde.";
  statusKind.value = "info";
}

function selectCustomer(customer: Customer) {
  selectedId.value = customer.id;
  Object.assign(form, {
    customer_number: customer.customer_number,
    name: customer.name,
    status: customer.status,
    details: { ...customer.details },
    standard_discount_percent: customer.standard_discount_percent,
    cash_discount_term_id: customer.cash_discount_term_id ?? null
  });
}

async function save() {
  pending.value = true;
  const payload = {
    ...form,
    standard_discount_percent: decimalString(form.standard_discount_percent)
  };
  const result = selectedId.value
    ? await apiPut<Customer>(`/api/v1/customers/${encodeURIComponent(selectedId.value)}`, payload)
    : await apiPost<Customer>("/api/v1/customers", payload);
  pending.value = false;
  if (!result.ok) {
    status.value = result.message;
    statusKind.value = "error";
    return;
  }
  selectedId.value = result.data.id;
  status.value = "Kunde gespeichert.";
  statusKind.value = "success";
  await loadCustomers();
}

async function deactivate() {
  if (!selectedId.value) return;
  const result = await apiDelete(`/api/v1/customers/${encodeURIComponent(selectedId.value)}`);
  status.value = result.ok ? "Kunde deaktiviert." : result.message;
  statusKind.value = result.ok ? "success" : "error";
  if (result.ok) {
    form.status = "inactive";
    await loadCustomers();
  }
}

onMounted(async () => {
  await Promise.all([loadCustomers(), loadCashDiscountTerms()]);
});
watch(
  () => liveUpdateState.revision,
  () => Promise.all([loadCustomers(), loadCashDiscountTerms()])
);
</script>

<template>
  <PageHeader title="Kunden" description="Kundenstamm, Rabatt und Kontaktdaten." />
  <div class="workspace-split">
    <section class="panel list-panel">
      <div class="section-title">
        <h2>Kundenliste</h2>
        <button type="button" @click="newCustomer">Neu</button>
      </div>
      <label class="field list-search"><span>Suche</span><input v-model="search" type="search" placeholder="Kundennummer oder Name" /></label>
      <button
        v-for="customer in filteredCustomers"
        :key="customer.id"
        type="button"
        class="list-row"
        :class="{ selected: selectedId === customer.id }"
        @click="selectCustomer(customer)"
      >
        <strong>{{ customer.customer_number }}</strong>
        <span>{{ customer.name }}</span>
        <small>{{ customer.status }}</small>
      </button>
      <p v-if="customers.length === 0" class="empty">Keine Kunden vorhanden.</p>
      <p v-else-if="filteredCustomers.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>Kundennummer</span><div class="readonly-value">{{ form.customer_number || "wird automatisch vergeben" }}</div></label>
          <label class="field"><span>Name</span><input v-model="form.name" required /></label>
          <label class="field">
            <span>Status</span>
            <select v-model="form.status">
              <option value="active">Aktiv</option>
              <option value="inactive">Inaktiv</option>
              <option value="blocked">Gesperrt</option>
            </select>
          </label>
          <label class="field"><span>Standardrabatt %</span><input v-model="form.standard_discount_percent" inputmode="decimal" required /></label>
          <label class="field">
            <span>Skonto-Regel</span>
            <select v-model="form.cash_discount_term_id">
              <option :value="null">Keine</option>
              <option v-for="term in cashDiscountTerms" :key="term.id" :value="term.id">{{ term.code }} - {{ term.name }}</option>
            </select>
          </label>
          <label class="field"><span>Straße</span><input v-model="form.details.street" /></label>
          <label class="field"><span>PLZ</span><input v-model="form.details.postal_code" /></label>
          <label class="field"><span>Ort</span><input v-model="form.details.city" /></label>
          <label class="field"><span>Land</span><input v-model="form.details.country" /></label>
          <label class="field"><span>E-Mail</span><input v-model="form.details.email" type="email" /></label>
          <label class="field"><span>Telefon</span><input v-model="form.details.phone" /></label>
        </div>
        <div class="form-actions">
          <button type="submit" :disabled="pending">Speichern</button>
          <button v-if="selectedId" type="button" class="secondary" :disabled="pending" @click="deactivate">Deaktivieren</button>
        </div>
        <FormStatus :message="status" :kind="statusKind" />
      </form>
    </section>
  </div>
</template>
