<?php
declare(strict_types=1);

namespace App\Modules\Subscriptions\Services;

use App\Core\App;
use App\Modules\Rules\Services\RuleEngine;

final class SubscriptionCalculator
{
    public static function calculateLateFine(int $memberId, string $financialYear): array
    {
        $db = App::getInstance()->db();

        $unpaidYears = $db->select(
            "SELECT financial_year, SUM(total_amount) as total, SUM(paid_amount) as paid
             FROM subscriptions WHERE member_id = ? AND status IN ('pending','overdue') AND financial_year <= ?
             GROUP BY financial_year ORDER BY financial_year ASC",
            [$memberId, $financialYear]
        );

        $totalFine = '0.00';
        $yearCount = count($unpaidYears);
        $fineDetails = [];

        $maxYearsData = RuleEngine::get('LATE_SUB_FINE_MAX_YEARS');
        $maxYears = $maxYearsData['years'] ?? 5;
        $dropYearsData = RuleEngine::get('LATE_SUB_DROP_YEARS');
        $dropYears = $dropYearsData['years'] ?? 5;

        $shouldDrop = $yearCount >= $dropYears;

        foreach ($unpaidYears as $idx => $uy) {
            $yearNum = $idx + 1;
            if ($yearNum > $maxYears) break;

            $unpaid = bcsub($uy['total'], $uy['paid'], 2);
            if (bccomp($unpaid, '0', 2) <= 0) continue;

            // Fine percentages: year 1 = 100%, year 2 = 200%, year 3 = 300%
            $ruleCode = 'LATE_SUB_FINE_YEAR_' . min($yearNum, 3);
            $fineData = RuleEngine::get($ruleCode);
            $finePct = $fineData['percentage_of_subscription'] ?? (string) ($yearNum * 100);

            $fineAmount = bcdiv(bcmul($unpaid, $finePct, 4), '100', 2);
            $totalFine = bcadd($totalFine, $fineAmount, 2);

            $fineDetails[] = [
                'financial_year' => $uy['financial_year'],
                'unpaid'         => $unpaid,
                'fine_percentage' => $finePct,
                'fine_amount'    => $fineAmount,
                'year_number'    => $yearNum,
            ];
        }

        return [
            'total_fine'    => $totalFine,
            'details'       => $fineDetails,
            'years_unpaid'  => $yearCount,
            'should_drop'   => $shouldDrop,
            'max_years'     => $maxYears,
        ];
    }
}