<?php

namespace App\Services\Billing;

use TCPDF;

/**
 * The page furniture: the logo block at the top and the footer at the bottom.
 *
 * A subclass because TCPDF draws headers and footers through overridden
 * methods, and the footer has to repeat on every page — an invoice that runs to
 * two pages must carry the company's register and VAT numbers on both, or the
 * second page is not part of a valid invoice.
 *
 * The body is not built here. It is a Blade template rendered to HTML and
 * handed to writeHTML(), because a table of line items expressed as a hundred
 * Cell() calls with millimetre coordinates is a table nobody will ever adjust.
 */
final class InvoiceDocument extends TCPDF
{
    /** @var array<string, mixed> */
    private array $issuer = [];

    private string $logoFile = '';

    private string $pageLabel = 'Seite';

    /** @param array<string, mixed> $issuer */
    public function setIssuer(array $issuer, string $logoFile = '', string $pageLabel = 'Seite'): void
    {
        $this->issuer = $issuer;
        $this->logoFile = $logoFile;
        $this->pageLabel = $pageLabel;
    }

    public function Header(): void // phpcs:ignore
    {
        if ($this->logoFile === '' || ! is_file($this->logoFile)) {
            return;
        }

        // Top right, height-constrained. Width 0 lets TCPDF keep the aspect
        // ratio — a logo squeezed to a fixed box is worse than none.
        $this->Image($this->logoFile, 140, 12, 0, 18, '', '', 'T', false, 300, 'R');
    }

    public function Footer(): void // phpcs:ignore
    {
        $this->SetY(-26);
        $this->SetFont('dejavusans', '', 6.5);
        $this->SetTextColor(110, 110, 122);

        $columns = [
            [
                $this->issuer['name'] ?? '',
                $this->issuer['address'] ?? '',
                trim(($this->issuer['postcode'] ?? '').' '.($this->issuer['city'] ?? '')),
            ],
            [
                $this->issuer['phone'] ?? '',
                $this->issuer['email'] ?? '',
                $this->issuer['website'] ?? '',
            ],
            [
                $this->issuer['register_number'] ?? '',
                $this->issuer['vat_id'] ?? '',
                $this->issuer['register_court'] ?? '',
            ],
            [
                $this->issuer['bank_name'] ?? '',
                $this->issuer['iban'] ?? '',
                $this->issuer['bic'] ?? '',
            ],
        ];

        // A hairline above it, the same one the totals block uses, so the page
        // reads as one document rather than two halves.
        $this->SetDrawColor(233, 233, 238);
        $this->Line(20, $this->GetY() - 3, 190, $this->GetY() - 3);

        $width = 42.5;

        foreach ($columns as $index => $lines) {
            $this->SetXY(20 + ($index * $width), -24);
            // Empty entries are dropped rather than printed as blank lines: a
            // company with no register number should not have a gap where one
            // would be.
            $this->MultiCell($width - 2, 3, implode("\n", array_filter($lines, fn ($l) => trim((string) $l) !== '')), 0, 'L', false, 0, '', '', true, 0, false, true, 0, 'T');
        }

        $this->SetXY(150, -30);
        $this->SetFont('dejavusans', '', 6.5);
        $this->Cell(40, 3, $this->pageLabel.' '.$this->getAliasNumPage().'/'.$this->getAliasNbPages(), 0, 0, 'R');
    }
}
