<?php

namespace App\Billing\Service;

use App\Billing\ValueObject\Money;
use App\Billing\ValueObject\ShareBreakdown;
use App\Insurance\ValueObject\CoverageRule;

class BillingCalculator
{
    /**
     * محاسبه‌ی سهم برای یک آیتم.
     * ترتیب: کل → پوشش پایه (با سقف) → باقیمانده → پوشش مکمل روی باقیمانده (با سقف) → فرانشیز سهم بیمار.
     */
    public function calculateItem(
        Money $total,
        ?CoverageRule $base,
        ?CoverageRule $supplementary,
    ): ShareBreakdown {
        $baseShare = Money::zero();
        $remaining = $total;

        if ($base !== null && $base->covered) {
            $baseShare = $total->percent($base->coveragePercent);
            if ($base->ceilingRials !== null) {
                $baseShare = $baseShare->min(new Money($base->ceilingRials));
            }
            $remaining = $total->sub($baseShare);
        }

        $suppShare = Money::zero();
        if ($supplementary !== null && $supplementary->covered) {
            $suppShare = $remaining->percent($supplementary->coveragePercent);
            if ($supplementary->ceilingRials !== null) {
                $suppShare = $suppShare->min(new Money($supplementary->ceilingRials));
            }
            $remaining = $remaining->sub($suppShare);
        }

        // فرانشیز سهم بیمار است؛ از سهم بیمه کم نمی‌کند ولی سهم بیمار از کل بیشتر نمی‌شود.
        $franchise = new Money(
            ($base?->franchiseRials ?? 0) + ($supplementary?->franchiseRials ?? 0)
        );
        $patient = $remaining->add($franchise)->min($total);

        return new ShareBreakdown(
            totalRials:         $total->rials,
            baseInsuranceRials: $baseShare->rials,
            supplementaryRials: $suppShare->rials,
            patientRials:       $patient->rials,
        );
    }
}
