<?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;

class PermissionRequestController extends Controller
{
    public function index(Request $request): Response
    {
        $this->authorize('hr.permissions.view');
        $db = App::getInstance()->db();

        $status = $request->get('status', '');
        $month = $request->get('month', date('Y-m'));
        $where = "DATE_FORMAT(p.permission_date, '%Y-%m') = ?";
        $params = [$month];

        if ($status) {
            $where .= ' AND p.status = ?';
            $params[] = $status;
        }

        $permissions = $db->select(
            "SELECT p.*, e.full_name_ar as employee_name, e.employee_number,
                    ap.full_name_ar as approved_by_name
             FROM hr_permission_requests p
             JOIN employees e ON e.id = p.employee_id
             LEFT JOIN employees ap ON ap.id = p.approved_by
             WHERE {$where}
             ORDER BY p.permission_date DESC",
            $params
        );

        return $this->view('HR.Views.permissions.index', [
            'permissions' => $permissions,
            'status' => $status,
            'month' => $month,
        ]);
    }

    public function create(Request $request): Response
    {
        $this->authorize('hr.permissions.create');
        $db = App::getInstance()->db();

        $employees = $db->select("SELECT id, full_name_ar, employee_number FROM employees WHERE is_archived = 0 AND employment_status = 'active' ORDER BY full_name_ar");

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

    public function store(Request $request): Response
    {
        $this->authorize('hr.permissions.create');
        $db = App::getInstance()->db();

        $employeeId = (int) $request->post('employee_id');
        $startTime = $request->post('start_time');
        $endTime = $request->post('end_time');

        $startMin = self::timeToMinutes($startTime);
        $endMin = self::timeToMinutes($endTime);
        $hours = ($endMin - $startMin) / 60;

        $monthTotal = $db->selectOne(
            "SELECT COALESCE(SUM(hours), 0) as total FROM hr_permission_requests
             WHERE employee_id = ? AND status IN ('pending','approved')
             AND DATE_FORMAT(permission_date, '%Y-%m') = ?",
            [$employeeId, date('Y-m', strtotime($request->post('permission_date')))]
        );

        $db->insert('hr_permission_requests', [
            'employee_id' => $employeeId,
            'permission_date' => $request->post('permission_date'),
            'start_time' => $startTime,
            'end_time' => $endTime,
            'hours' => number_format($hours, 2),
            'reason' => $request->post('reason'),
            'status' => 'pending',
            'monthly_total_hours' => bcadd((string) ($monthTotal['total'] ?? '0'), number_format($hours, 2), 2),
        ]);

        return $this->redirect('/hr/permissions')->withSuccess('تم تقديم طلب الإذن');
    }

    public function approve(Request $request, string $id): Response
    {
        $this->authorize('hr.permissions.approve');
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();

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

        return $this->redirect('/hr/permissions')->withSuccess('تم اعتماد الإذن');
    }

    public function reject(Request $request, string $id): Response
    {
        $this->authorize('hr.permissions.approve');
        $db = App::getInstance()->db();

        $db->update('hr_permission_requests', ['status' => 'rejected'], 'id = ?', [(int) $id]);

        return $this->redirect('/hr/permissions')->withSuccess('تم رفض الإذن');
    }

    private static function timeToMinutes(string $time): int
    {
        $parts = explode(':', $time);
        return ((int) $parts[0]) * 60 + ((int) ($parts[1] ?? 0));
    }
}
