/**
 * Credit-note PDF rendering via @react-pdf/renderer.
 *
 * Phase 7. Renders the same brand identity as the invoice PDF
 * (hexagon logo, issuer block, layout) with one accent override:
 * red instead of emerald. That difference is enough to make voids
 * and refunds visually unmistakable from an invoice at a glance,
 * while keeping every other element (logo shape, fonts, structure,
 * issuer info, page footer) identical so the document family reads
 * as one brand.
 *
 * Brand + Logo come from lib/pdf-brand. Edit there to change
 * issuer info, colours, or the logo glyph — both invoice and
 * credit-note PDFs pick the changes up.
 */

import React from "react";
import {
  Document,
  Page,
  Text,
  View,
  StyleSheet,
  renderToBuffer,
} from "@react-pdf/renderer";
import type { CreditNote, Invoice } from "@/types";
import { BRAND, Logo } from "./pdf-brand";


// ---------------------------------------------------------------------------
// Localized strings
// ---------------------------------------------------------------------------

interface CreditNoteStrings {
  creditNote: string;
  creditNoteNumber: string;
  issueDate: string;
  billTo: string;
  attentionPrefix: string;
  referenceInvoice: string;
  reason: string;
  voidLineLabel: string;
  refundLineLabel: string;
  subtotal: string;
  vatLabel: string;
  totalCredited: string;
  footerVoidNote: string;
  footerRefundNote: string;
  vatNoteSwiss: string;
  vatNoteReverseCharge: string;
  vatNoteOutOfScope: string;
}

const MESSAGES: Record<string, CreditNoteStrings> = {
  de: {
    creditNote: "Gutschrift",
    creditNoteNumber: "Gutschrift-Nr.",
    issueDate: "Ausstellungsdatum",
    billTo: "Empfänger",
    attentionPrefix: "z.Hd.",
    referenceInvoice: "Bezug Rechnung",
    reason: "Begründung",
    voidLineLabel: "Stornierung Rechnung {number}",
    refundLineLabel: "Rückerstattung Rechnung {number}",
    subtotal: "Zwischensumme",
    vatLabel: "MWST",
    totalCredited: "Gesamtbetrag Gutschrift",
    footerVoidNote:
      "Diese Gutschrift storniert die oben referenzierte Rechnung. Ein Zahlungsausgleich ist nicht erforderlich.",
    footerRefundNote:
      "Diese Gutschrift dokumentiert die Rückerstattung des oben genannten Betrags. Die Auszahlung erfolgt über den ursprünglichen Zahlungsweg.",
    vatNoteSwiss:
      "MWST gemäss schweizerischem Mehrwertsteuergesetz (MWSTG).",
    vatNoteReverseCharge:
      "Reverse Charge: Steuerschuldnerschaft des Leistungsempfängers nach Art. 196 EU-MwStSyst-RL bzw. nationaler Umsetzung.",
    vatNoteOutOfScope:
      "Leistung ausserhalb des Geltungsbereichs der schweizerischen MWST.",
  },
  en: {
    creditNote: "Credit note",
    creditNoteNumber: "Credit note no.",
    issueDate: "Issue date",
    billTo: "Bill to",
    attentionPrefix: "Attn:",
    referenceInvoice: "Reference invoice",
    reason: "Reason",
    voidLineLabel: "Void of invoice {number}",
    refundLineLabel: "Refund for invoice {number}",
    subtotal: "Subtotal",
    vatLabel: "VAT",
    totalCredited: "Total credited",
    footerVoidNote:
      "This credit note voids the referenced invoice. No payment is required.",
    footerRefundNote:
      "This credit note documents the refund of the amount above. Settlement occurs via the original payment method.",
    vatNoteSwiss:
      "VAT charged in accordance with Swiss VAT law (MWSTG).",
    vatNoteReverseCharge:
      "Reverse charge: VAT to be accounted for by the recipient per Art. 196 EU VAT Directive or national implementation.",
    vatNoteOutOfScope:
      "Service supplied outside the scope of Swiss VAT.",
  },
  fr: {
    creditNote: "Note de crédit",
    creditNoteNumber: "N° de note de crédit",
    issueDate: "Date d'émission",
    billTo: "Destinataire",
    attentionPrefix: "À l'attention de",
    referenceInvoice: "Facture de référence",
    reason: "Motif",
    voidLineLabel: "Annulation de la facture {number}",
    refundLineLabel: "Remboursement de la facture {number}",
    subtotal: "Sous-total",
    vatLabel: "TVA",
    totalCredited: "Total du crédit",
    footerVoidNote:
      "Cette note de crédit annule la facture référencée ci-dessus. Aucun paiement n'est requis.",
    footerRefundNote:
      "Cette note de crédit documente le remboursement du montant ci-dessus. Le règlement s'effectue via le moyen de paiement initial.",
    vatNoteSwiss:
      "TVA facturée conformément à la loi suisse sur la TVA (LTVA).",
    vatNoteReverseCharge:
      "Autoliquidation : TVA à acquitter par le destinataire selon l'art. 196 de la directive TVA UE ou sa mise en œuvre nationale.",
    vatNoteOutOfScope:
      "Prestation hors du champ d'application de la TVA suisse.",
  },
  it: {
    creditNote: "Nota di credito",
    creditNoteNumber: "N. nota di credito",
    issueDate: "Data di emissione",
    billTo: "Destinatario",
    attentionPrefix: "c.a.",
    referenceInvoice: "Fattura di riferimento",
    reason: "Motivo",
    voidLineLabel: "Annullamento della fattura {number}",
    refundLineLabel: "Rimborso della fattura {number}",
    subtotal: "Subtotale",
    vatLabel: "IVA",
    totalCredited: "Totale accreditato",
    footerVoidNote:
      "Questa nota di credito annulla la fattura sopra indicata. Non è richiesto alcun pagamento.",
    footerRefundNote:
      "Questa nota di credito documenta il rimborso dell'importo sopra indicato. Il regolamento avviene tramite il metodo di pagamento originale.",
    vatNoteSwiss:
      "IVA addebitata in conformità alla legge svizzera sull'IVA (LIVA).",
    vatNoteReverseCharge:
      "Inversione contabile: IVA dovuta dal destinatario ai sensi dell'art. 196 della direttiva IVA UE o della sua attuazione nazionale.",
    vatNoteOutOfScope:
      "Prestazione fuori dal campo di applicazione dell'IVA svizzera.",
  },
};

function pickStrings(locale: string): CreditNoteStrings {
  return MESSAGES[locale] ?? MESSAGES.de;
}

// Swiss number formatting — matches billing-pdf for consistency
function fmtChf(n: number): string {
  const fixed = n.toFixed(2);
  const [intPart, decPart] = fixed.split(".");
  const withSep = intPart.replace(/\B(?=(\d{3})+(?!\d))/g, "'");
  return decPart ? `${withSep}.${decPart}` : withSep;
}

function fmtDate(iso: string, locale: string): string {
  const [y, m, d] = iso.split("T")[0].split("-").map(Number);
  if (locale === "en") {
    return new Date(Date.UTC(y, m - 1, d)).toLocaleDateString("en-US", {
      year: "numeric",
      month: "short",
      day: "numeric",
    });
  }
  return `${String(d).padStart(2, "0")}.${String(m).padStart(2, "0")}.${y}`;
}

function pickVatNote(
  invoice: Invoice,
  strings: CreditNoteStrings
): string | null {
  const country = invoice.billingSnapshot.country?.toUpperCase();
  const hasVat = invoice.billingSnapshot.vatNumber?.trim();
  if (country === "CH" || country === "LI") return strings.vatNoteSwiss;
  if (hasVat) return strings.vatNoteReverseCharge;
  return strings.vatNoteOutOfScope;
}

// ---------------------------------------------------------------------------
// Styles
// ---------------------------------------------------------------------------

const styles = StyleSheet.create({
  page: {
    paddingTop: 36,
    paddingBottom: 50,
    paddingHorizontal: 50,
    fontSize: 10,
    fontFamily: "Helvetica",
    color: BRAND.textColor,
  },
  headerRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    marginBottom: 32,
  },
  logoBlock: { flexDirection: "row", alignItems: "center" },
  brandName: {
    fontSize: 16,
    color: BRAND.primaryDark,
    marginLeft: 8,
    fontFamily: "Helvetica-Bold",
  },
  issuerBlock: { textAlign: "right", fontSize: 8.5, color: BRAND.mutedColor },
  issuerName: { fontSize: 11, color: BRAND.primaryDark, marginBottom: 2 },
  docTitle: {
    fontSize: 22,
    color: BRAND.primaryDark,
    marginBottom: 8,
    fontFamily: "Helvetica-Bold",
  },
  metaTable: {
    flexDirection: "row",
    justifyContent: "space-between",
    marginBottom: 20,
  },
  metaCol: { flexDirection: "column", minWidth: 140 },
  metaLabel: { fontSize: 8, color: BRAND.mutedColor, marginBottom: 2 },
  metaValue: { fontSize: 10 },
  billTo: {
    marginBottom: 24,
    padding: 8,
    backgroundColor: "#f7f7f5",
    borderLeftWidth: 3,
    borderLeftColor: BRAND.primary,
  },
  billToLabel: { fontSize: 8, color: BRAND.mutedColor, marginBottom: 4 },
  billToName: { fontSize: 11, marginBottom: 2 },
  amountTable: {
    borderTopWidth: 1,
    borderTopColor: BRAND.borderColor,
    borderBottomWidth: 1,
    borderBottomColor: BRAND.borderColor,
    marginBottom: 16,
  },
  amountHeader: {
    flexDirection: "row",
    backgroundColor: BRAND.primaryDark,
    color: "#ffffff",
    paddingVertical: 5,
    paddingHorizontal: 6,
    fontSize: 9,
    fontFamily: "Helvetica-Bold",
  },
  amountRow: {
    flexDirection: "row",
    paddingVertical: 8,
    paddingHorizontal: 6,
    borderBottomWidth: 1,
    borderBottomColor: "#f0f0f0",
  },
  amountDesc: { flex: 1 },
  amountValue: { width: 90, textAlign: "right" },
  totals: { marginLeft: "auto", width: 220, marginBottom: 20 },
  totalsRow: {
    flexDirection: "row",
    justifyContent: "space-between",
    paddingVertical: 3,
  },
  totalsLabel: { color: BRAND.mutedColor, fontSize: 10 },
  totalsValue: { fontSize: 10 },
  totalsGrand: {
    flexDirection: "row",
    justifyContent: "space-between",
    borderTopWidth: 1,
    borderTopColor: BRAND.primaryDark,
    paddingTop: 6,
    marginTop: 4,
  },
  totalsGrandLabel: {
    color: BRAND.primaryDark,
    fontSize: 11,
    fontFamily: "Helvetica-Bold",
  },
  totalsGrandValue: {
    color: BRAND.primaryDark,
    fontSize: 11,
    textAlign: "right",
    fontFamily: "Helvetica-Bold",
  },
  reasonBox: {
    marginTop: 4,
    marginBottom: 18,
    padding: 8,
    backgroundColor: "#fafafa",
    borderLeftWidth: 2,
    borderLeftColor: BRAND.borderColor,
  },
  reasonLabel: {
    fontSize: 8,
    color: BRAND.mutedColor,
    marginBottom: 2,
    textTransform: "uppercase",
    letterSpacing: 0.5,
  },
  reasonText: { fontSize: 9.5, color: BRAND.textColor },
  noteBox: {
    marginTop: 12,
    padding: 8,
    fontSize: 8.5,
    color: BRAND.mutedColor,
    lineHeight: 1.5,
  },
  footer: {
    position: "absolute",
    bottom: 24,
    left: 50,
    right: 50,
    fontSize: 7.5,
    color: BRAND.mutedColor,
    textAlign: "center",
    borderTopWidth: 0.5,
    borderTopColor: BRAND.borderColor,
    paddingTop: 6,
  },
});

interface CreditNotePdfProps {
  creditNote: CreditNote;
  invoice: Invoice;
}

function CreditNotePdfDocument({ creditNote, invoice }: CreditNotePdfProps) {
  const strings = pickStrings(creditNote.locale);
  const snap = creditNote.billingSnapshot;
  const vatNote = pickVatNote(invoice, strings);
  const amountLabelTemplate =
    creditNote.kind === "void" ? strings.voidLineLabel : strings.refundLineLabel;
  const amountLabel = amountLabelTemplate.replace(
    "{number}",
    invoice.invoiceNumber
  );
  const footerNote =
    creditNote.kind === "void" ? strings.footerVoidNote : strings.footerRefundNote;
  // Stored convention: amount_chf is gross (incl. VAT),
  // vat_amount_chf is the VAT portion. Subtotal computed for
  // display.
  const subtotal = creditNote.amountChf - creditNote.vatAmountChf;
  return (
    <Document>
      <Page size="A4" style={styles.page}>
        {/* Header — SAME hexagon logo as the invoice, tinted red.
            Issuer block from BRAND.issuer (shared with invoice). */}
        <View style={styles.headerRow}>
          <View style={styles.logoBlock}>
            <Logo size={42} color={BRAND.primary} />
            <Text style={styles.brandName}>{BRAND.name}</Text>
          </View>
          <View style={styles.issuerBlock}>
            <Text style={styles.issuerName}>{BRAND.issuer.legalName}</Text>
            <Text>{BRAND.issuer.addressLine1}</Text>
            <Text>{BRAND.issuer.addressLine2}</Text>
            <Text>{BRAND.issuer.postalCity}</Text>
            <Text>{BRAND.issuer.country}</Text>
            <Text>{BRAND.issuer.email}</Text>
            <Text>{BRAND.issuer.web}</Text>
            {BRAND.issuer.vatNumber && (
              <Text>MWST-Nr. {BRAND.issuer.vatNumber}</Text>
            )}
          </View>
        </View>

        <Text style={styles.docTitle}>{strings.creditNote}</Text>

        <View style={styles.metaTable}>
          <View style={styles.metaCol}>
            <Text style={styles.metaLabel}>{strings.creditNoteNumber}</Text>
            <Text style={styles.metaValue}>{creditNote.creditNoteNumber}</Text>
          </View>
          <View style={styles.metaCol}>
            <Text style={styles.metaLabel}>{strings.issueDate}</Text>
            <Text style={styles.metaValue}>
              {fmtDate(creditNote.issuedAt, creditNote.locale)}
            </Text>
          </View>
          <View style={styles.metaCol}>
            <Text style={styles.metaLabel}>{strings.referenceInvoice}</Text>
            <Text style={styles.metaValue}>{invoice.invoiceNumber}</Text>
          </View>
        </View>

        <View style={styles.billTo}>
          <Text style={styles.billToLabel}>{strings.billTo}</Text>
          <Text style={styles.billToName}>{snap.companyName}</Text>
          {snap.contactName && snap.contactName.trim().length > 0 && (
            <Text>
              {strings.attentionPrefix} {snap.contactName}
            </Text>
          )}
          <Text>{snap.streetAddress}</Text>
          <Text>
            {snap.postalCode} {snap.city}
          </Text>
          <Text>{snap.country}</Text>
          {snap.vatNumber && <Text>MWST/VAT: {snap.vatNumber}</Text>}
        </View>

        <View style={styles.amountTable}>
          <View style={styles.amountHeader}>
            <Text style={styles.amountDesc}> </Text>
            <Text style={styles.amountValue}>CHF</Text>
          </View>
          <View style={styles.amountRow}>
            <Text style={styles.amountDesc}>{amountLabel}</Text>
            <Text style={styles.amountValue}>{fmtChf(subtotal)}</Text>
          </View>
        </View>

        <View style={styles.totals}>
          <View style={styles.totalsRow}>
            <Text style={styles.totalsLabel}>{strings.subtotal}</Text>
            <Text style={styles.totalsValue}>CHF {fmtChf(subtotal)}</Text>
          </View>
          {creditNote.vatAmountChf > 0 && (
            <View style={styles.totalsRow}>
              <Text style={styles.totalsLabel}>
                {strings.vatLabel} ({Number(invoice.vatRate).toFixed(1)}%)
              </Text>
              <Text style={styles.totalsValue}>
                CHF {fmtChf(creditNote.vatAmountChf)}
              </Text>
            </View>
          )}
          <View style={styles.totalsGrand}>
            <Text style={styles.totalsGrandLabel}>{strings.totalCredited}</Text>
            <Text style={styles.totalsGrandValue}>
              CHF {fmtChf(creditNote.amountChf)}
            </Text>
          </View>
        </View>

        {creditNote.reason && creditNote.reason.trim().length > 0 && (
          <View style={styles.reasonBox}>
            <Text style={styles.reasonLabel}>{strings.reason}</Text>
            <Text style={styles.reasonText}>{creditNote.reason}</Text>
          </View>
        )}

        <View style={styles.noteBox}>
          <Text>{footerNote}</Text>
          {vatNote && <Text style={{ marginTop: 6 }}>{vatNote}</Text>}
        </View>

        <Text style={styles.footer} fixed>
          {BRAND.issuer.legalName} · {creditNote.creditNoteNumber}
        </Text>
      </Page>
    </Document>
  );
}

export async function renderCreditNotePdf(
  creditNote: CreditNote,
  invoice: Invoice
): Promise<Buffer> {
  const doc = <CreditNotePdfDocument creditNote={creditNote} invoice={invoice} />;
  return renderToBuffer(doc) as unknown as Buffer;
}
