<script setup>
import { computed, onMounted, ref, watch } from "vue";
import { useRoute, useRouter } from "vue-router";
import BaseButton from "../../../components/base/BaseButton.vue";
import BaseModal from "../../../components/base/BaseModal.vue";
import Button from "primevue/button";
import DatePicker from "primevue/datepicker";
import InputGroup from "primevue/inputgroup";
import InputGroupAddon from "primevue/inputgroupaddon";
import InputNumber from "primevue/inputnumber";
import InputText from "primevue/inputtext";
import Select from "primevue/select";
import Textarea from "primevue/textarea";
import CustomerForm from "../../customers/views/partials/CustomerForm.vue";
import { useCustomerForm } from "../../customers/composables/useCustomers.js";
import { useAuth } from "../../../composables/useAuth.js";
import { useBaseToast } from "../../../composables/useBaseToast.js";
import { formatDateYmd } from "../../../composables/useDataTableFilters.js";
import { api, ensureCsrf } from "../../../services/api.js";
import {
  bookInvoice,
  deleteInvoice,
  fetchInvoice,
  fetchInvoiceMeta,
  fetchInvoicePdfBlob,
  saveInvoiceDraft,
  sendInvoice,
  sendInvoiceCopy,
} from "../composables/useInvoices.js";

const route = useRoute();
const router = useRouter();
const toast = useBaseToast();
const { permissions } = useAuth();

const canEdit = computed(() => permissions.value.includes("invoices.edit"));
const canCreate = computed(() => permissions.value.includes("invoices.create"));
const canDelete = computed(() => permissions.value.includes("invoices.delete"));
const canSend = computed(() => permissions.value.includes("invoices.send"));
const canBook = computed(() => permissions.value.includes("invoices.book"));

const meta = ref({
  vat_rates: [],
  default_vat_rate_id: null,
  items_enabled: false,
  items: [],
});

const customerOptions = ref([]);
const loading = ref(true);
const saving = ref(false);
const invoice = ref(null);
const customerDialog = ref(false);
const customerDraft = ref({});
const { create: createCustomer, errors: customerErrors, saving: customerSaving } =
  useCustomerForm();

/** API dates: YYYY-MM-DD strings (BaseDatePicker single mode). */
const form = ref({
  type: "invoice",
  customer_id: null,
  credited_invoice_id: null,
  invoice_date: "",
  expiration_date: "",
  description: "",
  email_body: "",
  lines: [],
});

function addDaysYmd(ymd, n) {
  const m = String(ymd || "").match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!m) return "";
  const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
  d.setDate(d.getDate() + n);
  return formatDateYmd(d);
}

function blankLine() {
  const vid = meta.value.default_vat_rate_id ?? meta.value.vat_rates?.[0]?.id;
  return {
    description: "",
    quantity: 1,
    unit_price_ex_vat: 0,
    vat_rate_id: vid,
    item_id: null,
  };
}

async function loadCustomers() {
  await ensureCsrf();
  const { data } = await api.get("/api/customers", {
    params: { per_page: 500, sort_by: "name", sort_dir: "asc" },
  });
  const rows = data.data ?? [];
  customerOptions.value = rows.map((c) => ({
    label: c.name,
    value: c.id,
    email: c.email,
  }));
}

async function loadMeta() {
  meta.value = await fetchInvoiceMeta();
}

function applyItemToLine(line, itemId) {
  const item = meta.value.items?.find((i) => i.id === itemId);
  if (!item) return;
  line.description = item.name || line.description;
  line.unit_price_ex_vat = Number(item.default_unit_price_ex_vat ?? 0);
  if (item.default_vat_rate_id) {
    line.vat_rate_id = item.default_vat_rate_id;
  }
}

const computedTotals = computed(() => {
  const sign = form.value.type === "credit_note" ? -1 : 1;
  let ex = 0;
  let vat = 0;
  for (const ln of form.value.lines ?? []) {
    const rateObj = meta.value.vat_rates?.find((r) => r.id === ln.vat_rate_id);
    const rate = Number(rateObj?.rate_percent ?? 0);
    const q = Number(ln.quantity ?? 0);
    const unit = Number(ln.unit_price_ex_vat ?? 0);
    const lineEx = Math.round(q * unit * 100) / 100;
    const lineVat = Math.round(lineEx * (rate / 100) * 100) / 100;
    ex += lineEx;
    vat += lineVat;
  }
  const inc = ex + vat;
  return {
    subtotal_ex_vat: sign * ex,
    total_vat: sign * vat,
    total_inc_vat: sign * inc,
  };
});

const isLocked = computed(() => invoice.value?.is_locked === true);

const itemSelectOptions = computed(() =>
  (meta.value.items ?? []).map((i) => ({
    label: i.name,
    value: i.id,
  })),
);

async function initNew() {
  const today = formatDateYmd(new Date());
  form.value.type =
    route.name === "invoices-credit-new" ? "credit_note" : "invoice";
  const cf = route.query.credit_for ? Number(route.query.credit_for) : null;
  form.value.credited_invoice_id = Number.isFinite(cf) ? cf : null;
  form.value.invoice_date = today;
  paymentDays.value = 14;
  form.value.expiration_date = addDaysYmd(today, 14);
  form.value.lines = [blankLine()];
}

async function loadExisting(id) {
  const data = await fetchInvoice(id);
  invoice.value = data;
  form.value.type = data.type;
  form.value.customer_id = data.customer_id;
  form.value.credited_invoice_id = data.credited_invoice_id;
  form.value.invoice_date = data.invoice_date || "";
  form.value.expiration_date = data.expiration_date || "";
  form.value.description = data.description ?? "";
  form.value.email_body = data.email_body ?? "";
  form.value.lines =
    (data.lines ?? []).map((l) => ({
      id: l.id,
      description: l.description,
      quantity: l.quantity,
      unit_price_ex_vat: l.unit_price_ex_vat,
      vat_rate_id: l.vat_rate_id,
      item_id: l.item_id,
    })) || [];
  if (!form.value.lines.length) {
    form.value.lines = [blankLine()];
  }
  syncPaymentDaysFromDates();
}

async function boot() {
  loading.value = true;
  try {
    await loadMeta();
    await loadCustomers();
    if (route.name === "invoices-new" || route.name === "invoices-credit-new") {
      await initNew();
    } else if (route.params.id) {
      await loadExisting(route.params.id);
    }
  } catch (e) {
    toast.error(
      e?.response?.data?.message ?? "Onbekende fout",
      "Laden mislukt",
      5000,
    );
  } finally {
    loading.value = false;
  }
}

watch(
  () => route.params.id,
  async (id) => {
    if (!id) return;
    loading.value = true;
    try {
      await loadExisting(id);
    } finally {
      loading.value = false;
    }
  },
);

onMounted(boot);

function ymdForApi(v) {
  if (typeof v === "string" && /^\d{4}-\d{2}-\d{2}$/.test(v.trim())) {
    return v.trim();
  }
  if (v instanceof Date && !Number.isNaN(v.getTime())) {
    return formatDateYmd(v);
  }
  return "";
}

function buildPayload() {
  return {
    type: form.value.type,
    customer_id: form.value.customer_id,
    credited_invoice_id:
      form.value.type === "credit_note"
        ? form.value.credited_invoice_id
        : null,
    invoice_date: ymdForApi(form.value.invoice_date),
    expiration_date: ymdForApi(form.value.expiration_date),
    description: form.value.description || null,
    email_body: form.value.email_body || null,
    lines: form.value.lines.map((l) => ({
      description: l.description,
      quantity: l.quantity,
      unit_price_ex_vat: l.unit_price_ex_vat,
      vat_rate_id: l.vat_rate_id,
      item_id: l.item_id || null,
    })),
  };
}

async function onSaveDraft() {
  if (!canEdit.value && !canCreate.value) return;
  saving.value = true;
  try {
    const payload = buildPayload();
    const id = invoice.value?.id ?? route.params.id;
    const saved = await saveInvoiceDraft(payload, id ? Number(id) : null);
    invoice.value = saved;
    toast.success("Opgeslagen");
    if (!route.params.id && saved?.id) {
      await router.replace({
        name: "invoices-edit",
        params: { id: String(saved.id) },
      });
    }
  } catch (e) {
    toast.error(e?.response?.data?.message ?? "Opslaan mislukt", "Fout", 6000);
  } finally {
    saving.value = false;
  }
}

async function onSend() {
  if (!canSend.value) return;
  saving.value = true;
  try {
    await onSaveDraft();
    const id = invoice.value?.id ?? route.params.id;
    await sendInvoice(Number(id), {});
    toast.success("Verzonden", null, 4000);
    await boot();
  } catch (e) {
    toast.error(
      e?.response?.data?.message ?? "",
      "Verzenden mislukt",
      6000,
    );
  } finally {
    saving.value = false;
  }
}

async function onBook() {
  if (!canBook.value) return;
  saving.value = true;
  try {
    await onSaveDraft();
    const id = invoice.value?.id ?? route.params.id;
    await bookInvoice(Number(id));
    toast.success("Geboekt", null, 4000);
    await boot();
  } catch (e) {
    toast.error(e?.response?.data?.message ?? "", "Boeken mislukt", 6000);
  } finally {
    saving.value = false;
  }
}

async function onSendCopy() {
  if (!canSend.value) return;
  saving.value = true;
  try {
    const id = invoice.value?.id ?? route.params.id;
    await sendInvoiceCopy(Number(id), {});
    toast.success("Kopie verzonden", null, 4000);
  } catch (e) {
    toast.error(e?.response?.data?.message ?? "", "Mislukt", 6000);
  } finally {
    saving.value = false;
  }
}

async function onPdf() {
  try {
    const id = invoice.value?.id ?? route.params.id;
    const blob = await fetchInvoicePdfBlob(Number(id));
    const url = URL.createObjectURL(blob);
    window.open(url, "_blank", "noopener");
    setTimeout(() => URL.revokeObjectURL(url), 60_000);
  } catch {
    toast.error("PDF openen mislukt.");
  }
}

async function onDelete() {
  if (!canDelete.value) return;
  try {
    const id = invoice.value?.id ?? route.params.id;
    await deleteInvoice(Number(id));
    toast.success("Verwijderd");
    router.push({ name: "invoices" });
  } catch (e) {
    toast.error(e?.response?.data?.message ?? "", "Verwijderen mislukt", 6000);
  }
}

function openCustomerDialog() {
  customerDraft.value = {
    name: "",
    email: "",
    phone: "",
    website: "",
    notes: "",
    is_active: true,
  };
  customerDialog.value = true;
}

async function submitCustomer(payload) {
  try {
    const c = await createCustomer(payload);
    customerDialog.value = false;
    await loadCustomers();
    form.value.customer_id = c.id;
    toast.success("Klant aangemaakt");
  } catch {
    /* validation on CustomerForm */
  }
}

function addLine() {
  form.value.lines.push(blankLine());
}

function removeLine(i) {
  form.value.lines.splice(i, 1);
  if (!form.value.lines.length) {
    form.value.lines.push(blankLine());
  }
}

const vatSelectOptions = computed(() =>
  (meta.value.vat_rates ?? []).map((r) => ({
    label: `${r.label} (${r.rate_percent}%)${r.is_active === false ? " — inactief" : ""}`,
    value: r.id,
  })),
);

/** BTW-tweede dropdown — tekst zoals in voorbeeldscherm. */
const vatSelectLineOptions = computed(() =>
  (meta.value.vat_rates ?? []).map((r) => ({
    label: `${r.label} (${r.rate_percent}%) (af te dragen)`,
    value: r.id,
  })),
);

const PAYMENT_PROFILE_OPTIONS = [
  { label: "7 dagen", days: 7 },
  { label: "14 dagen", days: 14 },
  { label: "30 dagen", days: 30 },
  { label: "60 dagen", days: 60 },
  { label: "90 dagen", days: 90 },
];

const paymentDays = ref(14);

function parseYmdToDate(s) {
  if (!s || typeof s !== "string") return null;
  const m = s.match(/^(\d{4})-(\d{2})-(\d{2})$/);
  if (!m) return null;
  const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
  return Number.isNaN(d.getTime()) ? null : d;
}

function daysBetweenYmd(startYmd, endYmd) {
  const a = parseYmdToDate(startYmd);
  const b = parseYmdToDate(endYmd);
  if (!a || !b) return null;
  return Math.round((b.getTime() - a.getTime()) / 86400000);
}

function nearestPaymentDays(diff) {
  if (diff == null || !Number.isFinite(diff)) return 14;
  const opts = PAYMENT_PROFILE_OPTIONS.map((o) => o.days);
  let best = opts[0];
  let bestDist = Math.abs(diff - best);
  for (const d of opts) {
    const dist = Math.abs(diff - d);
    if (dist < bestDist) {
      bestDist = dist;
      best = d;
    }
  }
  return best;
}

function syncPaymentDaysFromDates() {
  const inv = form.value.invoice_date;
  const exp = form.value.expiration_date;
  const diff = daysBetweenYmd(inv, exp);
  if (diff != null && diff >= 0) {
    paymentDays.value = nearestPaymentDays(diff);
  }
}

function applyPaymentDays() {
  const inv = form.value.invoice_date;
  if (!inv) return;
  form.value.expiration_date = addDaysYmd(inv, paymentDays.value);
}

const invoiceDateModel = computed({
  get: () => parseYmdToDate(form.value.invoice_date),
  set: (d) => {
    form.value.invoice_date =
      d instanceof Date && !Number.isNaN(d.getTime())
        ? formatDateYmd(d)
        : "";
    applyPaymentDays();
  },
});

const expirationDateModel = computed({
  get: () => parseYmdToDate(form.value.expiration_date),
  set: (d) => {
    form.value.expiration_date =
      d instanceof Date && !Number.isNaN(d.getTime())
        ? formatDateYmd(d)
        : "";
    syncPaymentDaysFromDates();
  },
});

const isCreateRoute = computed(() =>
  ["invoices-new", "invoices-credit-new"].includes(String(route.name ?? "")),
);

const invoiceNumberPreview = computed(() => {
  if (invoice.value?.document_number) {
    return invoice.value.document_number;
  }
  const ymd = form.value.invoice_date;
  const m = String(ymd || "").match(/^(\d{4})/);
  const y = m ? m[1] : new Date().getFullYear();
  return `${y}.001`;
});

const invoiceNumberWarning = computed(
  () => !form.value.customer_id && !invoice.value?.document_number,
);

function formatEuro(n) {
  const v = Number(n ?? 0);
  return new Intl.NumberFormat("nl-NL", {
    style: "currency",
    currency: "EUR",
  }).format(v);
}

const vatBreakdownByRate = computed(() => {
  const map = new Map();
  const sign = form.value.type === "credit_note" ? -1 : 1;
  for (const ln of form.value.lines ?? []) {
    const rateObj = meta.value.vat_rates?.find((r) => r.id === ln.vat_rate_id);
    const rate = Number(rateObj?.rate_percent ?? 0);
    const q = Number(ln.quantity ?? 0);
    const unit = Number(ln.unit_price_ex_vat ?? 0);
    const lineEx = Math.round(q * unit * 100) / 100;
    const lineVat = Math.round(lineEx * (rate / 100) * 100) / 100;
    const id = rateObj?.id ?? "x";
    const prev = map.get(id) ?? {
      label: rateObj
        ? `${rateObj.label} (${rateObj.rate_percent}%) (af te dragen)`
        : "BTW",
      amount: 0,
    };
    prev.amount += sign * lineVat;
    map.set(id, prev);
  }
  return [...map.values()].filter((x) => Math.abs(x.amount) > 0.0001);
});

function onPaymentProfileChange(days) {
  paymentDays.value = Number(days);
  applyPaymentDays();
}

function onCancelDraft() {
  router.push({ name: "invoices" });
}

async function onFinalizeInvoice() {
  if (canBook.value) {
    await onBook();
    return;
  }
  if (canSend.value) {
    await onSend();
    return;
  }
  toast.warn(
    "Je hebt geen recht om de factuur vast te leggen.",
    "Geen rechten",
    4000,
  );
}
</script>

<template>
  <div class="p-4 md:p-6 max-w-5xl mx-auto">
    <div v-if="loading" class="text-surface-600">Laden…</div>

    <div v-else class="flex flex-col gap-6">
      <!-- Definitieve factuur -->
      <template v-if="isLocked">
        <div class="flex flex-wrap items-center justify-between gap-3">
          <div>
            <h1 class="text-2xl font-semibold m-0">
              {{ form.type === "credit_note" ? "Creditnota" : "Factuur" }}
              <span
                v-if="invoice?.document_number"
                class="text-surface-500 text-lg font-normal"
              >
                {{ invoice.document_number }}
              </span>
            </h1>
            <p class="text-amber-700 text-sm m-0 mt-1">
              Definitief — alleen PDF en kopiëren per e-mail mogelijk.
            </p>
          </div>
          <div class="flex flex-wrap gap-2">
            <BaseButton
              v-if="invoice?.type === 'invoice' && isLocked"
              variant="secondary"
              label="Nieuwe creditnota"
              @click="
                router.push({
                  name: 'invoices-credit-new',
                  query: { credit_for: String(invoice.id) },
                })
              "
            />
            <BaseButton
              v-if="invoice?.id"
              variant="secondary"
              icon="file"
              label="PDF"
              @click="onPdf"
            />
            <BaseButton
              v-if="canSend"
              variant="secondary"
              label="E-mail kopie"
              @click="onSendCopy"
            />
          </div>
        </div>

        <div
          v-if="invoice"
          class="border-t border-surface-200 dark:border-surface-700 pt-4 flex flex-col gap-4 text-sm"
        >
        <p class="m-0">
          <strong>Klant:</strong>
          {{ invoice.customer?.name ?? "—" }}
        </p>
        <p class="m-0 whitespace-pre-wrap">
          <strong>Omschrijving:</strong>
          {{ invoice.description || "—" }}
        </p>
        <div class="overflow-x-auto rounded-lg border border-surface-200">
          <table class="w-full text-sm border-collapse min-w-[640px]">
            <thead>
              <tr class="bg-surface-50 dark:bg-surface-900">
                <th class="border border-surface-200 p-3 text-left font-medium">
                  Omschrijving
                </th>
                <th class="border border-surface-200 p-3 text-right font-medium">
                  Aantal
                </th>
                <th class="border border-surface-200 p-3 text-right font-medium">
                  Ex
                </th>
                <th class="border border-surface-200 p-3 text-right font-medium">
                  BTW
                </th>
                <th class="border border-surface-200 p-3 text-right font-medium">
                  Incl.
                </th>
              </tr>
            </thead>
            <tbody>
              <tr v-for="ln in invoice.lines ?? []" :key="ln.id">
                <td class="border border-surface-200 p-3">{{ ln.description }}</td>
                <td class="border border-surface-200 p-3 text-right tabular-nums">
                  {{ ln.quantity }}
                </td>
                <td class="border border-surface-200 p-3 text-right tabular-nums">
                  {{ Number(ln.line_total_ex_vat).toFixed(2) }}
                </td>
                <td class="border border-surface-200 p-3 text-right tabular-nums">
                  {{ Number(ln.line_vat_amount).toFixed(2) }}
                </td>
                <td class="border border-surface-200 p-3 text-right tabular-nums">
                  {{ Number(ln.line_total_inc_vat).toFixed(2) }}
                </td>
              </tr>
            </tbody>
          </table>
        </div>
        <div
          class="grid grid-cols-1 sm:grid-cols-3 gap-4 font-medium tabular-nums"
        >
          <div>Ex btw: € {{ Number(invoice.subtotal_ex_vat).toFixed(2) }}</div>
          <div>BTW: € {{ Number(invoice.total_vat).toFixed(2) }}</div>
          <div>Incl.: € {{ Number(invoice.total_inc_vat).toFixed(2) }}</div>
        </div>
        </div>
      </template>

      <!-- Concept / bewerken — layout zoals ontwerp -->
      <template v-else>
        <div
          class="rounded-xl border border-surface-200 dark:border-surface-700 bg-surface-0 dark:bg-surface-950 p-6 md:p-8"
        >
          <h1
            class="text-xl md:text-2xl font-semibold text-surface-900 dark:text-surface-0 m-0 mb-6"
          >
            <template v-if="form.type === 'credit_note'">Creditnota maken</template>
            <template v-else-if="isCreateRoute">Factuur maken</template>
            <template v-else>
              Factuur bewerken
              <span
                v-if="invoice?.id && !invoice?.document_number"
                class="text-surface-500 font-normal text-lg"
              >
                (concept)
              </span>
            </template>
          </h1>

          <div v-if="form.type === 'credit_note'" class="mb-6">
            <label
              class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
              >Gekoppelde factuur (ID)</label
            >
            <InputText
              class="w-full"
              :model-value="
                form.credited_invoice_id != null
                  ? String(form.credited_invoice_id)
                  : ''
              "
              placeholder="Factuur-ID"
              type="number"
              @update:model-value="
                (v) =>
                  (form.credited_invoice_id =
                    v !== '' && v != null ? Number(v) : null)
              "
            />
          </div>

          <div class="grid grid-cols-1 lg:grid-cols-2 gap-x-10 gap-y-5">
            <div class="flex flex-col gap-5">
              <div>
                <label
                  class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
                  >Klant</label
                >
                <div class="flex gap-2 items-start">
                  <Select
                    v-model="form.customer_id"
                    :options="customerOptions"
                    option-label="label"
                    option-value="value"
                    placeholder="Selecteer of voeg toe..."
                    class="flex-1 min-w-0"
                    filter
                    show-clear
                  />
                  <Button
                    type="button"
                    outlined
                    class="shrink-0 !px-3"
                    aria-label="Nieuwe klant"
                    @click="openCustomerDialog"
                  >
                    +
                  </Button>
                </div>
              </div>

              <div>
                <label
                  class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
                  >Factuurnummer</label
                >
                <InputGroup class="w-full">
                  <InputText
                    :model-value="invoiceNumberPreview"
                    fluid
                    readonly
                    class="flex-1"
                  />
                  <InputGroupAddon v-if="invoiceNumberWarning">
                    <i
                      class="pi pi-exclamation-triangle text-red-500"
                      aria-hidden="true"
                    />
                  </InputGroupAddon>
                  <InputGroupAddon>
                    <Button
                      type="button"
                      icon="pi pi-pencil"
                      text
                      rounded
                      severity="secondary"
                      title="Wordt definitief bij vastleggen"
                    />
                  </InputGroupAddon>
                </InputGroup>
              </div>

              <div>
                <label
                  class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
                  >Factuurdatum</label
                >
                <InputGroup class="w-full flex flex-wrap sm:flex-nowrap">
                  <DatePicker
                    v-model="invoiceDateModel"
                    show-icon
                    icon-display="input"
                    date-format="dd-mm-yy"
                    class="min-w-0 flex-1 [&_.p-inputtext]:w-full"
                  />
                  <InputGroupAddon>
                    <Button
                      type="button"
                      icon="pi pi-pencil"
                      text
                      rounded
                      severity="secondary"
                    />
                  </InputGroupAddon>
                </InputGroup>
              </div>
            </div>

            <div class="flex flex-col gap-5">
              <div>
                <label
                  class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
                  >Betaalprofiel</label
                >
                <Select
                  :model-value="paymentDays"
                  :options="PAYMENT_PROFILE_OPTIONS"
                  option-label="label"
                  option-value="days"
                  class="w-full"
                  @update:model-value="onPaymentProfileChange"
                />
              </div>

              <div>
                <label
                  class="block text-sm font-medium text-surface-700 dark:text-surface-300 mb-2"
                  >Vervaldatum</label
                >
                <InputGroup class="w-full flex flex-wrap sm:flex-nowrap">
                  <DatePicker
                    v-model="expirationDateModel"
                    show-icon
                    icon-display="input"
                    date-format="dd-mm-yy"
                    class="min-w-0 flex-1 [&_.p-inputtext]:w-full"
                  />
                  <InputGroupAddon>
                    <Button
                      type="button"
                      icon="pi pi-pencil"
                      text
                      rounded
                      severity="secondary"
                    />
                  </InputGroupAddon>
                </InputGroup>
              </div>
            </div>
          </div>

          <hr class="my-8 border-surface-200 dark:border-surface-700" />

          <div
            class="hidden md:grid md:grid-cols-12 md:gap-3 mb-2 text-xs font-medium text-surface-600 dark:text-surface-400 px-1"
          >
            <div class="col-span-5">Omschrijving</div>
            <div class="col-span-3">Rubriek &amp; Btw</div>
            <div class="col-span-2 text-right">Aantal</div>
            <div class="col-span-2 text-right">Bedrag</div>
          </div>

          <div class="flex flex-col gap-6">
            <div
              v-for="(line, idx) in form.lines"
              :key="idx"
              class="grid grid-cols-1 md:grid-cols-12 gap-3 items-start border-b border-surface-100 dark:border-surface-800 md:border-0 pb-6 md:pb-0 last:border-0 last:pb-0"
            >
              <div class="md:col-span-5 min-w-0">
                <span
                  class="md:hidden text-xs font-medium text-surface-600 mb-1 block"
                  >Omschrijving</span
                >
                <Textarea
                  v-model="line.description"
                  :rows="4"
                  class="w-full"
                  placeholder="Omschrijving..."
                />
              </div>

              <div class="md:col-span-3 flex flex-col gap-2 min-w-0">
                <span
                  class="md:hidden text-xs font-medium text-surface-600 mb-1"
                  >Rubriek &amp; Btw</span
                >
                <Select
                  v-if="meta.items_enabled"
                  :model-value="line.item_id"
                  :options="itemSelectOptions"
                  option-label="label"
                  option-value="value"
                  placeholder="Rubriek"
                  class="w-full"
                  show-clear
                  @update:model-value="
                    (v) => {
                      line.item_id = v;
                      if (v) applyItemToLine(line, v);
                    }
                  "
                />
                <Select
                  v-model="line.vat_rate_id"
                  :options="vatSelectLineOptions"
                  option-label="label"
                  option-value="value"
                  placeholder="BTW"
                  class="w-full"
                />
              </div>

              <div class="md:col-span-2 min-w-0">
                <span
                  class="md:hidden text-xs font-medium text-surface-600 mb-1 block"
                  >Aantal</span
                >
                <InputNumber
                  v-model="line.quantity"
                  :min="0"
                  :max-fraction-digits="4"
                  suffix=" x"
                  class="w-full"
                />
              </div>

              <div class="md:col-span-2 min-w-0">
                <span
                  class="md:hidden text-xs font-medium text-surface-600 mb-1 block"
                  >Bedrag</span
                >
                <InputGroup>
                  <InputGroupAddon>€</InputGroupAddon>
                  <InputNumber
                    v-model="line.unit_price_ex_vat"
                    mode="decimal"
                    :min-fraction-digits="2"
                    :max-fraction-digits="4"
                    class="w-full"
                  />
                </InputGroup>
              </div>

              <div
                class="md:col-span-12 flex justify-end -mt-2 md:-mt-4"
                v-if="form.lines.length > 1"
              >
                <Button
                  type="button"
                  icon="pi pi-trash"
                  text
                  rounded
                  severity="danger"
                  aria-label="Regel verwijderen"
                  @click="removeLine(idx)"
                />
              </div>
            </div>
          </div>

          <Button
            type="button"
            outlined
            severity="secondary"
            class="w-full mt-2 !border-dashed"
            icon="pi pi-plus"
            label="Regel toevoegen"
            @click="addLine"
          />

          <div
            class="mt-10 pt-6 border-t border-surface-200 dark:border-surface-700 flex flex-col items-end gap-2 text-sm"
          >
            <div class="flex justify-between w-full max-w-sm gap-8">
              <span class="text-surface-600 dark:text-surface-400"
                >Totaal exclusief btw</span
              >
              <span class="tabular-nums">{{
                formatEuro(computedTotals.subtotal_ex_vat)
              }}</span>
            </div>
            <template v-if="vatBreakdownByRate.length">
              <div
                v-for="(row, ri) in vatBreakdownByRate"
                :key="ri"
                class="flex justify-between w-full max-w-sm gap-8"
              >
                <span class="text-surface-600 dark:text-surface-400">{{
                  row.label
                }}</span>
                <span class="tabular-nums">{{ formatEuro(row.amount) }}</span>
              </div>
            </template>
            <div v-else class="flex justify-between w-full max-w-sm gap-8">
              <span class="text-surface-600 dark:text-surface-400">Btw</span>
              <span class="tabular-nums">{{
                formatEuro(computedTotals.total_vat)
              }}</span>
            </div>
            <div
              class="flex justify-between w-full max-w-sm gap-8 text-base font-semibold pt-3 mt-1 border-t border-surface-200 dark:border-surface-700"
            >
              <span>Totaal</span>
              <span class="tabular-nums">{{
                formatEuro(computedTotals.total_inc_vat)
              }}</span>
            </div>
          </div>

          <div class="mt-8 flex flex-wrap justify-end items-center gap-2 md:gap-3">
            <Button type="button" label="Annuleren" text @click="onCancelDraft" />
            <Button
              v-if="canEdit || canCreate"
              type="button"
              label="Opslaan als concept"
              outlined
              severity="secondary"
              :loading="saving"
              @click="onSaveDraft"
            />
            <Button
              type="button"
              label="Factuur vastleggen"
              :loading="saving"
              @click="onFinalizeInvoice"
            />
            <Button
              v-if="canDelete && invoice?.id"
              type="button"
              label="Verwijderen"
              text
              severity="danger"
              @click="onDelete"
            />
          </div>
        </div>
      </template>
    </div>

    <BaseModal
      v-model:visible="customerDialog"
      title="Nieuwe klant"
      width="32rem"
      class="max-w-lg"
    >
      <CustomerForm
        embedded
        :visible="customerDialog"
        :draft="customerDraft"
        :saving="customerSaving"
        :errors="customerErrors"
        title=""
        @submit="submitCustomer"
        @cancel="customerDialog = false"
      />
    </BaseModal>
  </div>
</template>
