<?php
/**
 * Kenya-oriented payroll helpers (Finance Act 2023 PAYE bands, configurable SHIF/NSSF/Housing).
 * Statutory figures must be verified against current KRA/NSSF/SHA regulations before production pay runs.
 */

if (!function_exists('hr_payroll_read_float_setting')) {
    function hr_payroll_read_float_setting(mysqli $conn, string $key, float $default): float
    {
        $v = hr_setting($conn, $key, (string)$default);
        return (float)$v;
    }

    /**
     * Monthly PAYE on taxable employment income (KES), after pension/NSSF-style exclusions already reflected in $taxableMonthly.
     * Uses KRA monthly bands effective July 2023 (10%–35%) and personal relief from hr_settings.
     */
    function hr_compute_paye_monthly(mysqli $conn, float $taxableMonthly): float
    {
        $relief = hr_payroll_read_float_setting($conn, 'PAYE_PERSONAL_RELIEF', 2400.0);
        $t = max(0, $taxableMonthly);
        $tax = 0.0;
        $remaining = $t;

        $slices = [
            [24000, 0.10],
            [8333, 0.25],
            [467667, 0.30],
            [300000, 0.325],
        ];
        foreach ($slices as $pair) {
            $width = $pair[0];
            $rate = $pair[1];
            if ($remaining <= 0) {
                break;
            }
            $chunk = min($remaining, $width);
            $tax += $chunk * $rate;
            $remaining -= $chunk;
        }
        if ($remaining > 0) {
            $tax += $remaining * 0.35;
        }
        return max(0, round($tax - $relief, 2));
    }

    /**
     * NSSF employee contribution (simplified Tier I + Tier II on monthly pensionable, capped at IEL).
     */
    function hr_compute_nssf_employee(mysqli $conn, float $pensionableMonthly): float
    {
        $lel = hr_payroll_read_float_setting($conn, 'NSSF_LEL', 7000.0);
        $iel = hr_payroll_read_float_setting($conn, 'NSSF_IEL', 36000.0);
        $rate = hr_payroll_read_float_setting($conn, 'NSSF_EE_RATE', 0.06);
        $p = max(0, min($pensionableMonthly, $iel));
        $tier1Base = min($p, $lel);
        $tier2Base = max(0, $p - $lel);
        return round($tier1Base * $rate + $tier2Base * $rate, 2);
    }

    function hr_compute_nssf_employer(mysqli $conn, float $pensionableMonthly): float
    {
        $rateEr = hr_payroll_read_float_setting($conn, 'NSSF_ER_RATE', 0.06);
        $lel = hr_payroll_read_float_setting($conn, 'NSSF_LEL', 7000.0);
        $iel = hr_payroll_read_float_setting($conn, 'NSSF_IEL', 36000.0);
        $p = max(0, min($pensionableMonthly, $iel));
        $tier1Base = min($p, $lel);
        $tier2Base = max(0, $p - $lel);
        return round($tier1Base * $rateEr + $tier2Base * $rateEr, 2);
    }

    function hr_compute_shif_employee(mysqli $conn, float $gross): float
    {
        $r = hr_payroll_read_float_setting($conn, 'SHIF_EE_RATE', 0.0275);
        return round(max(0, $gross) * $r, 2);
    }

    function hr_compute_shif_employer(mysqli $conn, float $gross): float
    {
        $r = hr_payroll_read_float_setting($conn, 'SHIF_ER_RATE', 0.0275);
        return round(max(0, $gross) * $r, 2);
    }

    function hr_compute_housing_employee(mysqli $conn, float $gross): float
    {
        $r = hr_payroll_read_float_setting($conn, 'HOUSING_EE_RATE', 0.015);
        return round(max(0, $gross) * $r, 2);
    }

    function hr_compute_housing_employer(mysqli $conn, float $gross): float
    {
        $r = hr_payroll_read_float_setting($conn, 'HOUSING_ER_RATE', 0.015);
        return round(max(0, $gross) * $r, 2);
    }

    /**
     * Taxable for PAYE: gross less deductible NSSF employee (capped) and voluntary pension (capped monthly).
     */
    function hr_compute_line(mysqli $conn, array $comp, float $pensionVoluntary = 0.0): array
    {
        $basic = (float)$comp['basic_salary'];
        $house = (float)$comp['housing_allowance'];
        $trans = (float)$comp['transport_allowance'];
        $other = (float)$comp['other_taxable_allowance'];
        $gross = round($basic + $house + $trans + $other, 2);

        $pensionCap = 30000.0;
        $pensionDed = min(max(0, $pensionVoluntary), $pensionCap);

        $nssfEe = hr_compute_nssf_employee($conn, $gross);
        $nssfEr = hr_compute_nssf_employer($conn, $gross);

        $taxable = max(0, round($gross - $nssfEe - $pensionDed, 2));
        $paye = hr_compute_paye_monthly($conn, $taxable);

        $shifEe = hr_compute_shif_employee($conn, $gross);
        $shifEr = hr_compute_shif_employer($conn, $gross);
        $hEe = hr_compute_housing_employee($conn, $gross);
        $hEr = hr_compute_housing_employer($conn, $gross);

        $otherDed = 0.0;
        $net = round($gross - $nssfEe - $shifEe - $hEe - $paye - $pensionDed - $otherDed, 2);

        $calc = [
            'gross_pay' => $gross,
            'taxable_pay' => $taxable,
            'nssf_employee' => $nssfEe,
            'nssf_employer' => $nssfEr,
            'shif_employee' => $shifEe,
            'shif_employer' => $shifEr,
            'housing_levy_ee' => $hEe,
            'housing_levy_er' => $hEr,
            'paye_tax' => $paye,
            'pension_voluntary' => $pensionDed,
            'other_deductions' => $otherDed,
            'net_pay' => $net,
        ];
        return $calc;
    }

    function hr_latest_compensation(mysqli $conn, int $employeeId, string $asOfDate): ?array
    {
        $sql = "SELECT * FROM hr_employee_compensation
                WHERE employee_id = ? AND effective_from <= ?
                AND (effective_to IS NULL OR effective_to >= ?)
                ORDER BY effective_from DESC LIMIT 1";
        $st = $conn->prepare($sql);
        $st->bind_param('iss', $employeeId, $asOfDate, $asOfDate);
        $st->execute();
        $row = $st->get_result()->fetch_assoc();
        $st->close();
        return $row ?: null;
    }
}
