<?php

namespace App\Billing\Service;

use App\Billing\Entity\Invoice;
use App\Patient\Entity\PatientSession;
use Psr\Log\LoggerInterface;

/**
 * مراجعهٔ بیمه‌دار باید صورتحساب نهایی‌شده داشته باشد — چون مطالبهٔ بیمه از دل همان
 * صورتحساب بیرون می‌آید و بدونش، مراجعه در داشبورد مطالبات اصلاً دیده نمی‌شود.
 *
 * تنها جای این قاعده همین‌جاست تا هر سه مسیرِ ساختِ مراجعه (ثبت دستی، ویرایش، و
 * قطعی‌کردن نوبت) یک رفتار داشته باشند؛ پراکندگیِ قبلیِ همین قاعده باعث شده بود
 * مراجعه‌های قطعی‌شده از نوبت هیچ‌وقت مطالبه نگیرند.
 */
class SessionBillingService
{
    public function __construct(
        private readonly InvoiceService  $invoiceService,
        private readonly LoggerInterface $logger,
    ) {}

    /**
     * صورتحساب مراجعه را می‌سازد و نهایی می‌کند. مراجعهٔ بدون بیمه دست‌نخورده می‌ماند.
     * شکست اینجا نباید ثبت مراجعه یا قطعی‌کردن نوبت را برگرداند.
     */
    public function ensureFinalizedInvoice(PatientSession $session, string $entityType, int $entityId): ?Invoice
    {
        if ($session->getInsuranceBaseId() === null && $session->getInsuranceSupplementaryId() === null) {
            return null;
        }

        try {
            $invoice = $this->invoiceService->createFromSession($session, $entityType, $entityId);
            $this->invoiceService->finalize($invoice);

            return $invoice;
        } catch (\Throwable $e) {
            $this->logger->error('finalizing the insured session invoice failed', [
                'session' => $session->getUuid(),
                'error'   => $e->getMessage(),
            ]);

            return null;
        }
    }
}
