<?php
declare(strict_types=1);

namespace App\Modules\HR\Services;

use App\Core\App;

final class TaxBracketService
{
    public static function calculateAnnualTax(string $annualTaxableIncome, ?string $date = null): array
    {
        $db = App::getInstance()->db();
        $date = $date ?? date('Y-m-d');

        $brackets = $db->select(
            "SELECT * FROM hr_tax_brackets WHERE effective_date <= ? AND is_active = 1 ORDER BY bracket_order ASC",
            [$date]
        );

        if (empty($brackets)) {
            return ['annual_tax' => '0.00', 'monthly_tax' => '0.00', 'effective_rate' => '0.00', 'breakdown' => []];
        }

        $totalExemption = '0.00';
        foreach ($brackets as $bracket) {
            if (bccomp((string) $bracket['annual_exemption'], '0', 2) > 0) {
                $totalExemption = (string) $bracket['annual_exemption'];
                break;
            }
        }

        $taxableAfterExemption = bcsub($annualTaxableIncome, $totalExemption, 2);
        if (bccomp($taxableAfterExemption, '0', 2) <= 0) {
            return ['annual_tax' => '0.00', 'monthly_tax' => '0.00', 'effective_rate' => '0.00', 'breakdown' => [], 'exemption' => $totalExemption];
        }

        $remainingIncome = $taxableAfterExemption;
        $totalTax = '0.00';
        $breakdown = [];

        foreach ($brackets as $bracket) {
            if (bccomp($remainingIncome, '0', 2) <= 0) break;

            $bracketSize = bcsub((string) $bracket['to_amount'], (string) $bracket['from_amount'], 2);
            $taxableInBracket = bccomp($remainingIncome, $bracketSize, 2) > 0 ? $bracketSize : $remainingIncome;
            $taxInBracket = bcmul($taxableInBracket, (string) $bracket['rate'], 2);

            $totalTax = bcadd($totalTax, $taxInBracket, 2);
            $remainingIncome = bcsub($remainingIncome, $taxableInBracket, 2);

            $breakdown[] = [
                'from' => $bracket['from_amount'],
                'to' => $bracket['to_amount'],
                'rate' => $bracket['rate'],
                'taxable_amount' => $taxableInBracket,
                'tax_amount' => $taxInBracket,
            ];
        }

        $monthlyTax = bcdiv($totalTax, '12', 2);
        $effectiveRate = bccomp($annualTaxableIncome, '0', 2) > 0
            ? bcmul(bcdiv($totalTax, $annualTaxableIncome, 6), '100', 2)
            : '0.00';

        return [
            'annual_tax' => $totalTax,
            'monthly_tax' => $monthlyTax,
            'effective_rate' => $effectiveRate,
            'exemption' => $totalExemption,
            'taxable_after_exemption' => $taxableAfterExemption,
            'breakdown' => $breakdown,
        ];
    }

    public static function calculateMonthlyTax(int $employeeId, string $monthlyGross, ?string $date = null): array
    {
        $annualGross = bcmul($monthlyGross, '12', 2);

        $db = App::getInstance()->db();
        $insurance = InsuranceCalculationService::calculate($employeeId, $date);
        $annualInsurance = bcmul($insurance['employee_share'], '12', 2);

        $annualTaxable = bcsub($annualGross, $annualInsurance, 2);

        $result = self::calculateAnnualTax($annualTaxable, $date);
        $result['gross_salary'] = $monthlyGross;
        $result['insurance_deduction'] = $insurance['employee_share'];

        return $result;
    }
}
