<?php
declare(strict_types=1);

namespace App\Modules\HR\Models;

use App\Core\Model;
use App\Core\App;
use App\Core\Pagination;

class HrAttendance extends Model
{
    protected static string $table = 'hr_attendance';
    protected static string $primaryKey = 'id';
    protected static bool $timestamps = true;
    protected static bool $softDelete = false;
    protected static bool $autoTrackAuthor = true;

    protected static array $fillable = [
        'employee_profile_id', 'attendance_date',
        'check_in_time', 'check_out_time', 'check_in_method', 'check_out_method',
        'actual_hours', 'overtime_hours', 'overtime_type',
        'late_minutes', 'early_leave_minutes',
        'status', 'is_ramadan_schedule', 'notes',
        'is_approved', 'approved_by', 'approved_at',
    ];

    public static function getStatuses(): array
    {
        return [
            'present'   => 'حاضر',
            'absent'    => 'غائب',
            'late'      => 'متأخر',
            'half_day'  => 'نصف يوم',
            'on_leave'  => 'في إجازة',
            'holiday'   => 'عطلة رسمية',
            'rest_day'  => 'يوم راحة',
        ];
    }

    public static function getCheckMethods(): array
    {
        return [
            'manual'      => 'يدوي',
            'fingerprint' => 'بصمة',
            'card'        => 'كارت',
            'face'        => 'وجه',
        ];
    }

    public static function getForEmployeeDate(int $profileId, string $date): ?array
    {
        $db = App::getInstance()->db();
        return $db->selectOne(
            "SELECT * FROM hr_attendance WHERE employee_profile_id = ? AND attendance_date = ?",
            [$profileId, $date]
        );
    }

    public static function getMonthly(int $profileId, int $year, int $month): array
    {
        $db = App::getInstance()->db();
        $startDate = sprintf('%04d-%02d-01', $year, $month);
        $endDate = date('Y-m-t', strtotime($startDate));

        return $db->select(
            "SELECT * FROM hr_attendance
             WHERE employee_profile_id = ? AND attendance_date BETWEEN ? AND ?
             ORDER BY attendance_date ASC",
            [$profileId, $startDate, $endDate]
        );
    }

    public static function getMonthlySummary(int $profileId, int $year, int $month): array
    {
        $db = App::getInstance()->db();
        $startDate = sprintf('%04d-%02d-01', $year, $month);
        $endDate = date('Y-m-t', strtotime($startDate));

        $row = $db->selectOne(
            "SELECT
                COUNT(*) as total_days,
                SUM(CASE WHEN status = 'present' THEN 1 ELSE 0 END) as present_days,
                SUM(CASE WHEN status = 'absent' THEN 1 ELSE 0 END) as absent_days,
                SUM(CASE WHEN status = 'late' THEN 1 ELSE 0 END) as late_days,
                SUM(CASE WHEN status = 'on_leave' THEN 1 ELSE 0 END) as leave_days,
                SUM(CASE WHEN status = 'holiday' THEN 1 ELSE 0 END) as holiday_days,
                COALESCE(SUM(actual_hours), 0) as total_actual_hours,
                COALESCE(SUM(overtime_hours), 0) as total_overtime_hours,
                COALESCE(SUM(late_minutes), 0) as total_late_minutes,
                COALESCE(SUM(early_leave_minutes), 0) as total_early_leave_minutes
             FROM hr_attendance
             WHERE employee_profile_id = ? AND attendance_date BETWEEN ? AND ?",
            [$profileId, $startDate, $endDate]
        );

        return $row ?: [];
    }

    public static function search(array $filters, int $perPage = 25, int $page = 1): array
    {
        $db = App::getInstance()->db();
        $where = '1=1';
        $params = [];

        if (!empty($filters['employee_profile_id'])) {
            $where .= ' AND a.employee_profile_id = ?';
            $params[] = (int) $filters['employee_profile_id'];
        }
        if (!empty($filters['date_from'])) {
            $where .= ' AND a.attendance_date >= ?';
            $params[] = $filters['date_from'];
        }
        if (!empty($filters['date_to'])) {
            $where .= ' AND a.attendance_date <= ?';
            $params[] = $filters['date_to'];
        }
        if (!empty($filters['status'])) {
            $where .= ' AND a.status = ?';
            $params[] = $filters['status'];
        }
        if (!empty($filters['department_id'])) {
            $where .= ' AND p.department_id = ?';
            $params[] = (int) $filters['department_id'];
        }

        $countRow = $db->selectOne(
            "SELECT COUNT(*) as cnt FROM hr_attendance a JOIN hr_employee_profiles p ON p.id = a.employee_profile_id WHERE {$where}",
            $params
        );
        $total = (int) ($countRow['cnt'] ?? 0);
        $offset = ($page - 1) * $perPage;

        $rows = $db->select(
            "SELECT a.*, CONCAT(p.first_name_ar, ' ', p.last_name_ar) as full_name_ar, p.employee_number, d.name_ar as department_name
             FROM hr_attendance a
             JOIN hr_employee_profiles p ON p.id = a.employee_profile_id
             LEFT JOIN hr_departments d ON d.id = p.department_id
             WHERE {$where}
             ORDER BY a.attendance_date DESC, p.first_name_ar ASC
             LIMIT {$perPage} OFFSET {$offset}",
            $params
        );

        return ['data' => $rows, 'pagination' => Pagination::paginate($total, $perPage, $page)];
    }
}
