<?php

namespace App\Services;

use App\Models\Business;

class BrandedPdfService
{
    public function generate(Business $business, string $title, array $lines, ?string $reference = null): string
    {
        $header = [
            $business->name ?: 'Microfinance',
            $title,
        ];
        if ($reference) $header[] = 'Reference: '.$reference;
        $header[] = '';
        $header[] = 'Registration: '.($business->registration_number ?: 'N/A').'   TIN: '.($business->tin ?: 'N/A');
        $header[] = 'Address: '.(collect([$business->address,$business->district,$business->region,$business->country])->filter()->join(', ') ?: 'N/A');
        $header[] = 'Phone: '.($business->phone ?: 'N/A').'   Email: '.($business->email ?: 'N/A');
        if ($business->website || $business->postal_address) {
            $header[] = 'Website: '.($business->website ?: 'N/A').'   Postal: '.($business->postal_address ?: 'N/A');
        }
        $header[] = str_repeat('-', 92);
        $header[] = '';

        $footer = [
            '',
            str_repeat('-', 92),
            'Generated from the permanent system record on '.now()->format('d M Y H:i').'.',
        ];

        return $this->pdf($this->wrapLines(array_merge($header, $lines, $footer)));
    }

    public function money(Business $business, string|int|float|null $amount): string
    {
        $value = (float) ($amount ?? 0);
        $formatted = match ($business->number_format) {
            '1.234,56' => number_format($value, 2, ',', '.'),
            '1234.56' => number_format($value, 2, '.', ''),
            default => number_format($value, 2, '.', ','),
        };
        return trim(($business->currency_symbol ?: $business->currency ?: '').' '.$formatted);
    }

    private function wrapLines(array $lines, int $width = 96): array
    {
        $out = [];
        foreach ($lines as $line) {
            $parts = $line === '' ? [''] : explode("\n", wordwrap((string) $line, $width, "\n", true));
            foreach ($parts as $part) $out[] = $part;
        }
        return $out;
    }

    private function pdf(array $lines): string
    {
        $pages = array_chunk($lines, 48);
        $objects = [1 => '<< /Type /Catalog /Pages 2 0 R >>', 3 => '<< /Type /Font /Subtype /Type1 /BaseFont /Helvetica >>'];
        $kids = [];

        foreach ($pages as $i => $pageLines) {
            $pageObj = 4 + ($i * 2);
            $contentObj = $pageObj + 1;
            $kids[] = $pageObj.' 0 R';
            $stream = "BT\n/F1 10 Tf\n50 792 Td\n14 TL\n";
            foreach ($pageLines as $line) $stream .= '('.$this->escape($line).") Tj\nT*\n";
            $stream .= 'ET';
            $objects[$pageObj] = '<< /Type /Page /Parent 2 0 R /MediaBox [0 0 595 842] /Resources << /Font << /F1 3 0 R >> >> /Contents '.$contentObj.' 0 R >>';
            $objects[$contentObj] = '<< /Length '.strlen($stream)." >>\nstream\n".$stream."\nendstream";
        }

        $objects[2] = '<< /Type /Pages /Kids ['.implode(' ', $kids).'] /Count '.count($pages).' >>';
        ksort($objects);
        $pdf = "%PDF-1.4\n";
        $offsets = [0];
        foreach ($objects as $number => $body) {
            $offsets[$number] = strlen($pdf);
            $pdf .= $number." 0 obj\n".$body."\nendobj\n";
        }
        $xref = strlen($pdf);
        $max = max(array_keys($objects));
        $pdf .= "xref\n0 ".($max + 1)."\n0000000000 65535 f \n";
        for ($i = 1; $i <= $max; $i++) $pdf .= sprintf('%010d 00000 n ', $offsets[$i] ?? 0)."\n";
        $pdf .= "trailer\n<< /Size ".($max + 1).' /Root 1 0 R >>'."\nstartxref\n{$xref}\n%%EOF";
        return $pdf;
    }

    private function escape(string $text): string
    {
        $text = iconv('UTF-8', 'Windows-1252//TRANSLIT//IGNORE', $text) ?: $text;
        return str_replace(['\\', '(', ')'], ['\\\\', '\\(', '\\)'], $text);
    }
}
