<?php
declare(strict_types=1);

namespace App\Modules\HR\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\HR\Models\HrInsuranceRecord;
use App\Modules\HR\Models\HrPayrollPeriod;
use App\Modules\HR\Models\HrEmployeeProfile;

class InsuranceController extends Controller
{
    public function index(Request $request): Response
    {
        $year = (int) $request->get('year', (int) date('Y'));

        $db = App::getInstance()->db();
        $periods = $db->select(
            "SELECT pp.id, pp.period_code, pp.year, pp.month, pp.status,
                    (SELECT COUNT(*) FROM hr_insurance_records ir WHERE ir.period_id = pp.id AND ir.is_archived = 0) as record_count,
                    (SELECT SUM(total_employee_share) FROM hr_insurance_records ir WHERE ir.period_id = pp.id AND ir.is_archived = 0) as total_employee_share,
                    (SELECT SUM(total_employer_share) FROM hr_insurance_records ir WHERE ir.period_id = pp.id AND ir.is_archived = 0) as total_employer_share
             FROM hr_payroll_periods pp
             WHERE pp.year = ? AND pp.is_archived = 0
             ORDER BY pp.month ASC",
            [$year]
        );

        return $this->view('HR.Views.insurance.index', [
            'periods' => $periods,
            'year'    => $year,
        ]);
    }

    public function periodRecords(Request $request, string $periodId): Response
    {
        $period = HrPayrollPeriod::find((int) $periodId);
        if (!$period) {
            return $this->redirect('/hr/insurance')->withError('فترة الرواتب غير موجودة');
        }

        $records = HrInsuranceRecord::getForPeriod((int) $periodId);
        $totals = HrInsuranceRecord::getPeriodTotals((int) $periodId);

        return $this->view('HR.Views.insurance.period_records', [
            'period'  => $period,
            'records' => $records,
            'totals'  => $totals,
        ]);
    }

    public function employeeHistory(Request $request, string $employeeId): Response
    {
        $profile = HrEmployeeProfile::find((int) $employeeId);
        if (!$profile) {
            return $this->redirect('/hr/insurance')->withError('الموظف غير موجود');
        }

        $year = (int) $request->get('year', (int) date('Y'));
        $records = HrInsuranceRecord::getForEmployee((int) $employeeId, $year);

        return $this->view('HR.Views.insurance.employee_history', [
            'profile' => $profile,
            'records' => $records,
            'year'    => $year,
        ]);
    }

    public function form1(Request $request): Response
    {
        $year = (int) $request->get('year', (int) date('Y'));
        $month = (int) $request->get('month', (int) date('m'));

        $db = App::getInstance()->db();

        // Form 1: New employee registration form
        // Get employees hired in the specified month
        $newEmployees = $db->select(
            "SELECT hp.*, d.name_ar as department_name, jt.name_ar as job_title_name
             FROM hr_employee_profiles hp
             LEFT JOIN hr_departments d ON d.id = hp.department_id
             LEFT JOIN hr_job_titles jt ON jt.id = hp.job_title_id
             WHERE YEAR(hp.hire_date) = ? AND MONTH(hp.hire_date) = ?
               AND hp.insurance_number IS NOT NULL
               AND hp.is_archived = 0
             ORDER BY hp.hire_date ASC",
            [$year, $month]
        );

        return $this->view('HR.Views.insurance.form1', [
            'employees' => $newEmployees,
            'year'      => $year,
            'month'     => $month,
        ]);
    }

    public function form2(Request $request): Response
    {
        $this->authorize('hr.insurance.view');

        $year = (int) $request->get('year', (int) date('Y'));
        $month = (int) $request->get('month', (int) date('m'));

        $db = App::getInstance()->db();

        // Form 2: Wage adjustment notification
        // Get salary adjustments (applied/approved) in the specified month from hr_salary_adjustments
        $adjustments = $db->select(
            "SELECT sa.previous_basic_salary, sa.new_basic_salary, sa.effective_date, sa.reason,
                    sa.adjustment_type,
                    CONCAT(hp.first_name_ar, ' ', hp.last_name_ar) as full_name,
                    hp.insurance_number, hp.national_id
             FROM hr_salary_adjustments sa
             JOIN employees e ON e.id = sa.employee_id
             JOIN hr_employee_profiles hp ON hp.employee_id = e.id
             WHERE YEAR(sa.effective_date) = ? AND MONTH(sa.effective_date) = ?
               AND sa.status IN ('approved', 'applied')
               AND hp.insurance_number IS NOT NULL
               AND hp.is_archived = 0
             ORDER BY sa.effective_date ASC",
            [$year, $month]
        );

        // Get company info from system_config
        $companyName = $db->selectOne(
            "SELECT config_value FROM system_config WHERE config_key = 'company.name_ar'",
            []
        );
        $insuranceNo = $db->selectOne(
            "SELECT config_value FROM system_config WHERE config_key = 'company.insurance_number'",
            []
        );

        return $this->view('HR.Views.insurance.form2', [
            'adjustments'     => $adjustments,
            'year'            => $year,
            'month'           => $month,
            'companyName'     => $companyName['config_value'] ?? null,
            'insuranceNumber' => $insuranceNo['config_value'] ?? null,
        ]);
    }

    public function form6(Request $request): Response
    {
        $year = (int) $request->get('year', (int) date('Y'));
        $month = (int) $request->get('month', (int) date('m'));

        $db = App::getInstance()->db();

        // Form 6: Monthly insurance contributions
        $periodId = $db->selectOne(
            "SELECT id FROM hr_payroll_periods WHERE year = ? AND month = ? AND is_archived = 0",
            [$year, $month]
        );

        $records = [];
        $totals = null;

        if ($periodId) {
            $records = $db->select(
                "SELECT ir.*, hp.employee_number, hp.first_name_ar, hp.last_name_ar,
                        hp.national_id, hp.insurance_number,
                        d.name_ar as department_name
                 FROM hr_insurance_records ir
                 JOIN hr_employee_profiles hp ON hp.id = ir.employee_profile_id
                 LEFT JOIN hr_departments d ON d.id = hp.department_id
                 WHERE ir.period_id = ? AND ir.is_archived = 0
                 ORDER BY hp.first_name_ar ASC",
                [(int) $periodId['id']]
            );

            $totals = HrInsuranceRecord::getPeriodTotals((int) $periodId['id']);
        }

        return $this->view('HR.Views.insurance.form6', [
            'records' => $records,
            'totals'  => $totals,
            'year'    => $year,
            'month'   => $month,
        ]);
    }
}
