<?php
declare(strict_types=1);

namespace App\Modules\HR\Services;

use App\Core\App;

final class InsuranceCalculationService
{
    public static function calculate(int $employeeId, ?string $date = null): array
    {
        $db = App::getInstance()->db();
        $date = $date ?? date('Y-m-d');

        $config = $db->selectOne(
            "SELECT * FROM hr_insurance_config WHERE effective_date <= ? AND is_active = 1 ORDER BY effective_date DESC LIMIT 1",
            [$date]
        );

        if (!$config) {
            return ['employer_share' => '0.00', 'employee_share' => '0.00', 'total' => '0.00', 'details' => []];
        }

        $salary = $db->selectOne(
            "SELECT basic_salary, variable_salary FROM hr_employee_salary_details
             WHERE employee_id = ? AND effective_date <= ?
             ORDER BY effective_date DESC LIMIT 1",
            [$employeeId, $date]
        );

        if (!$salary) {
            return ['employer_share' => '0.00', 'employee_share' => '0.00', 'total' => '0.00', 'details' => []];
        }

        $basicSalary = (string) $salary['basic_salary'];
        $variableSalary = (string) ($salary['variable_salary'] ?? '0');

        $insuredBasic = bccomp($basicSalary, (string) $config['basic_salary_cap'], 2) > 0
            ? (string) $config['basic_salary_cap']
            : $basicSalary;

        $insuredVariable = bccomp($variableSalary, (string) $config['variable_salary_cap'], 2) > 0
            ? (string) $config['variable_salary_cap']
            : $variableSalary;

        $employerBasic = bcmul($insuredBasic, (string) $config['employer_basic_rate'], 2);
        $employerVariable = bcmul($insuredVariable, (string) $config['employer_variable_rate'], 2);
        $employerShare = bcadd($employerBasic, $employerVariable, 2);

        $employeeBasic = bcmul($insuredBasic, (string) $config['employee_basic_rate'], 2);
        $employeeVariable = bcmul($insuredVariable, (string) $config['employee_variable_rate'], 2);
        $employeeShare = bcadd($employeeBasic, $employeeVariable, 2);

        $total = bcadd($employerShare, $employeeShare, 2);

        return [
            'employer_share' => $employerShare,
            'employee_share' => $employeeShare,
            'total' => $total,
            'details' => [
                'basic_salary' => $basicSalary,
                'variable_salary' => $variableSalary,
                'insured_basic' => $insuredBasic,
                'insured_variable' => $insuredVariable,
                'basic_cap' => (string) $config['basic_salary_cap'],
                'variable_cap' => (string) $config['variable_salary_cap'],
                'employer_basic_amount' => $employerBasic,
                'employer_variable_amount' => $employerVariable,
                'employee_basic_amount' => $employeeBasic,
                'employee_variable_amount' => $employeeVariable,
            ],
        ];
    }

    public static function calculateBulk(array $employeeIds, ?string $date = null): array
    {
        $results = [];
        foreach ($employeeIds as $id) {
            $results[$id] = self::calculate((int) $id, $date);
        }
        return $results;
    }
}
