<?php

declare( strict_types=1 );

namespace Brightfern\Invoice\Model;

/**
 * The internal EN 16931 invoice model — syntax-neutral. UblBisSerializer and
 * FacturXBuilder render it; InvoiceValidator checks it; the mapper builds it.
 * Deliberately free of any WordPress/WooCommerce coupling so it is unit-testable
 * and reusable for national formats (KSeF etc.) that are NOT Peppol.
 *
 * Document-level business terms:
 *   BT-1   Invoice number.
 *   BT-2   Issue date (YYYY-MM-DD).
 *   BT-3   Invoice type code (UNCL1001): 380 = invoice, 381 = credit note,
 *          384 = corrected invoice (not yet supported).
 *   BT-25  Preceding invoice reference (credit notes only).
 *   BT-5   Document currency code (ISO 4217).
 *   BT-6   VAT accounting currency (optional, when ≠ BT-5).
 *   BT-7   Value added tax point date.
 *   BT-9   Payment due date.
 *   BT-10  Buyer reference (often mandatory for B2G — e.g. the PO/Leitweg-ID).
 *   BT-13  Purchase order reference.
 *   BT-22  Invoice note.
 *   BT-24  Specification identifier (CustomizationID) — set by the serializer.
 *   BT-23  Business process (ProfileID) — set by the serializer.
 */
final class Invoice {
	public const TYPE_INVOICE     = '380';
	public const TYPE_CREDIT_NOTE = '381';

	public string $number = '';        // BT-1.
	public string $issueDate = '';     // BT-2, ISO 8601 date.
	public string $dueDate = '';       // BT-9.
	public string $typeCode = self::TYPE_INVOICE; // BT-3.
	public string $currency = 'EUR';   // BT-5.
	public string $taxPointDate = '';  // BT-7.
	public string $buyerReference = ''; // BT-10.
	public string $orderReference = ''; // BT-13.
	public string $note = '';          // BT-22.

	/** BT-25: the original invoice this document credits. Credit notes only. */
	public string $precedingInvoiceNumber = '';
	/** BT-26: issue date of the preceding invoice (optional). */
	public string $precedingInvoiceIssueDate = '';

	/**
	 * Two-letter country we are invoicing *for* — drives national format choice
	 * (BE → plain Peppol BIS UBL, FR → Factur-X). Not an EN 16931 term itself.
	 */
	public string $sellerCountry = '';

	public Party $seller;
	public Party $buyer;

	/** @var InvoiceLine[] */
	public array $lines = array();

	/** @var AllowanceCharge[] Document-level allowances/charges (BG-20/BG-21). */
	public array $allowanceCharges = array();

	/** @var TaxSubtotal[] VAT breakdown (BG-23), keyed by category|rate. */
	public array $taxSubtotals = array();

	public MonetaryTotals $totals;
	public Payment $payment;

	public function __construct() {
		$this->seller  = new Party();
		$this->buyer   = new Party();
		$this->totals  = new MonetaryTotals();
		$this->payment = new Payment();
	}

	public function isCreditNote(): bool {
		return self::TYPE_CREDIT_NOTE === $this->typeCode;
	}
}
