<?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\Core\Logger;
use App\Modules\HR\Models\HrEndOfService;
use App\Modules\HR\Models\HrEmployeeProfile;
use App\Modules\HR\Services\EndOfServiceService;

class EndOfServiceController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'q'      => trim((string) $request->get('q', '')),
            'status' => trim((string) $request->get('status', '')),
            'type'   => trim((string) $request->get('type', '')),
        ];

        $page = max(1, (int) $request->get('page', 1));
        $result = HrEndOfService::search($filters, 25, $page);

        return $this->view('HR.Views.end_of_service.index', [
            'records'    => $result['data'],
            'pagination' => $result['pagination'],
            'filters'    => $filters,
        ]);
    }

    public function create(Request $request): Response
    {
        $employees = HrEmployeeProfile::getActiveIds();

        return $this->view('HR.Views.end_of_service.form', [
            'record'    => null,
            'employees' => $employees,
        ]);
    }

    public function store(Request $request): Response
    {
        $profileId = (int) $request->post('employee_profile_id', 0);
        $terminationType = trim((string) $request->post('termination_type', ''));
        $terminationDate = trim((string) $request->post('termination_date', date('Y-m-d')));
        $terminationReason = trim((string) $request->post('termination_reason', ''));

        $errors = [];
        if ($profileId <= 0) {
            $errors[] = 'الموظف غير محدد';
        }
        if ($terminationType === '') {
            $errors[] = 'نوع إنهاء الخدمة مطلوب';
        }
        if ($terminationDate === '') {
            $errors[] = 'تاريخ إنهاء الخدمة مطلوب';
        }

        if (!empty($errors)) {
            $session = App::getInstance()->session();
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            $session->flash('_old_input', $request->all());
            return $this->redirect('/hr/end-of-service/create');
        }

        $db = App::getInstance()->db();
        $employee = $this->currentEmployee();

        $recordId = $db->insert('hr_end_of_service', [
            'employee_profile_id' => $profileId,
            'termination_type'    => $terminationType,
            'termination_date'    => $terminationDate,
            'termination_reason'  => $terminationReason ?: null,
            'status'              => 'draft',
            'created_at'          => date('Y-m-d H:i:s'),
            'updated_at'          => date('Y-m-d H:i:s'),
            'created_by'          => $employee ? (int) $employee->id : null,
        ]);

        return $this->redirect('/hr/end-of-service/' . $recordId)->withSuccess('تم إنشاء سجل نهاية الخدمة بنجاح');
    }

    public function show(Request $request, string $id): Response
    {
        $record = HrEndOfService::find((int) $id);
        if (!$record) {
            return $this->redirect('/hr/end-of-service')->withError('السجل غير موجود');
        }

        $profile = HrEmployeeProfile::find((int) $record->employee_profile_id);

        $db = App::getInstance()->db();
        $approver = $record->approved_by
            ? $db->selectOne("SELECT name FROM employees WHERE id = ?", [(int) $record->approved_by])
            : null;

        return $this->view('HR.Views.end_of_service.show', [
            'record'   => $record,
            'profile'  => $profile,
            'approver' => $approver,
        ]);
    }

    public function calculate(Request $request, string $id): Response
    {
        $record = HrEndOfService::find((int) $id);
        if (!$record) {
            return $this->redirect('/hr/end-of-service')->withError('السجل غير موجود');
        }

        if (!in_array($record->status, ['draft', 'calculated'], true)) {
            return $this->redirect('/hr/end-of-service/' . $id)->withError('لا يمكن إعادة الحساب في هذه الحالة');
        }

        $result = EndOfServiceService::calculate(
            (int) $record->employee_profile_id,
            $record->termination_date,
            $record->termination_type
        );

        if (!$result['success']) {
            return $this->redirect('/hr/end-of-service/' . $id)->withError($result['error']);
        }

        $db = App::getInstance()->db();
        $db->update('hr_end_of_service', [
            'years_of_service'      => $result['years_of_service'],
            'last_basic_salary'     => $result['last_basic_salary'],
            'severance_amount'      => $result['severance_amount'],
            'notice_compensation'   => $result['notice_compensation'],
            'leave_compensation'    => $result['leave_compensation'],
            'other_compensation'    => '0.00',
            'total_entitlements'    => $result['total_entitlements'],
            'outstanding_loans'     => $result['outstanding_loans'],
            'other_deductions'      => '0.00',
            'net_settlement'        => $result['net_settlement'],
            'calculation_json'      => json_encode($result['breakdown'], JSON_UNESCAPED_UNICODE),
            'status'                => 'calculated',
            'updated_at'            => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        Logger::info("End of service calculated", ['record_id' => (int) $id, 'net_settlement' => $result['net_settlement']]);

        return $this->redirect('/hr/end-of-service/' . $id)->withSuccess(
            'تم حساب مستحقات نهاية الخدمة: ' . number_format((float) $result['net_settlement'], 2) . ' ج.م'
        );
    }

    public function approve(Request $request, string $id): Response
    {
        $record = HrEndOfService::find((int) $id);
        if (!$record) {
            return $this->redirect('/hr/end-of-service')->withError('السجل غير موجود');
        }

        if ($record->status !== 'calculated') {
            return $this->redirect('/hr/end-of-service/' . $id)->withError('يجب حساب المستحقات أولاً');
        }

        $db = App::getInstance()->db();
        $employee = $this->currentEmployee();

        $db->update('hr_end_of_service', [
            'status'      => 'approved',
            'approved_by' => $employee ? (int) $employee->id : null,
            'approved_at' => date('Y-m-d H:i:s'),
            'updated_at'  => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        // Update employee status to terminated
        $db->update('hr_employee_profiles', [
            'employment_status'  => 'terminated',
            'termination_date'   => $record->termination_date,
            'termination_type'   => $record->termination_type,
            'termination_reason' => $record->termination_reason,
            'updated_at'         => date('Y-m-d H:i:s'),
        ], '`id` = ? AND `is_archived` = 0', [(int) $record->employee_profile_id]);

        Logger::info("End of service approved", ['record_id' => (int) $id]);

        return $this->redirect('/hr/end-of-service/' . $id)->withSuccess('تم اعتماد نهاية الخدمة');
    }

    public function markPaid(Request $request, string $id): Response
    {
        $record = HrEndOfService::find((int) $id);
        if (!$record) {
            return $this->redirect('/hr/end-of-service')->withError('السجل غير موجود');
        }

        if ($record->status !== 'approved') {
            return $this->redirect('/hr/end-of-service/' . $id)->withError('يجب اعتماد نهاية الخدمة أولاً');
        }

        $db = App::getInstance()->db();
        $employee = $this->currentEmployee();
        $paymentDate = trim((string) $request->post('payment_date', date('Y-m-d')));

        $db->update('hr_end_of_service', [
            'status'       => 'paid',
            'paid_date'    => $paymentDate,
            'updated_at'   => date('Y-m-d H:i:s'),
            'updated_by'   => $employee ? (int) $employee->id : null,
        ], '`id` = ?', [(int) $id]);

        Logger::info("End of service paid", ['record_id' => (int) $id, 'payment_date' => $paymentDate]);

        return $this->redirect('/hr/end-of-service/' . $id)->withSuccess('تم صرف مستحقات نهاية الخدمة');
    }
}
