<?php

declare(strict_types=1);

namespace App\Modules\Email;

use App\Core\View\Template;
use App\Modules\Accounting\ReceiptRepository;
use App\Modules\Settings\ReceiptConfigRepository;
use Dompdf\Dompdf;

final class AttachmentGenerator
{
    public function __construct(
        private readonly ReceiptRepository $receipts,
        private readonly ReceiptConfigRepository $receiptConfigs,
        private readonly Template $template
    ) {
    }

    /**
     * @param array<string, mixed> $order
     * @return array{filename: string, content: string, mime: string}|null
     */
    public function generate(string $type, array $order): ?array
    {
        return match ($type) {
            'receipt' => $this->generateReceiptPdf($order),
            default => null,
        };
    }

    /**
     * @param array<string, mixed> $order
     * @return array{filename: string, content: string, mime: string}|null
     */
    private function generateReceiptPdf(array $order): ?array
    {
        $orderId = (int) ($order['id'] ?? 0);
        if ($orderId <= 0) {
            return null;
        }

        $receipts = $this->receipts->findByOrderId($orderId);
        if ($receipts === []) {
            return null;
        }

        $receipt = $receipts[0];
        $receiptId = (int) ($receipt['id'] ?? 0);

        $fullReceipt = $this->receipts->findById($receiptId);
        if ($fullReceipt === null) {
            return null;
        }

        $data = $this->buildReceiptViewData($fullReceipt);

        $html = $this->template->render('receipts/print', $data);

        $dompdf = new Dompdf();
        $dompdf->loadHtml($html);
        $dompdf->setPaper('A4');
        $dompdf->render();

        $pdfContent = $dompdf->output();
        if ($pdfContent === null || $pdfContent === '') {
            return null;
        }

        $filename = str_replace(['/', '\\'], '_', (string) ($fullReceipt['receipt_number'] ?? 'paragon')) . '.pdf';

        return [
            'filename' => $filename,
            'content' => $pdfContent,
            'mime' => 'application/pdf',
        ];
    }

    /**
     * @param array<string, mixed> $receipt
     * @return array<string, mixed>
     */
    private function buildReceiptViewData(array $receipt): array
    {
        $seller = json_decode((string) ($receipt['seller_data_json'] ?? '{}'), true);
        $buyer = ($receipt['buyer_data_json'] ?? null) !== null
            ? json_decode((string) $receipt['buyer_data_json'], true)
            : null;
        $items = json_decode((string) ($receipt['items_json'] ?? '[]'), true);

        $configName = '';
        $config = $this->receiptConfigs->findById((int) ($receipt['config_id'] ?? 0));
        if ($config !== null) {
            $configName = (string) ($config['name'] ?? '');
        }

        return [
            'receipt' => $receipt,
            'seller' => is_array($seller) ? $seller : [],
            'buyer' => is_array($buyer) ? $buyer : null,
            'items' => is_array($items) ? $items : [],
            'configName' => $configName,
        ];
    }
}
