<?php
declare(strict_types=1);

namespace CronJobs;

use App\Core\Database;
use App\Core\Logger;

/**
 * Daily: alerts 30 days before employee document expiry (national ID, insurance forms, etc.).
 */
class HrDocumentExpiryJob
{
    private Database $db;
    public function __construct(Database $db) { $this->db = $db; }

    public function shouldRun(): bool
    {
        return true; // Runs daily
    }

    public function run(): array
    {
        $today = date('Y-m-d');
        $alertDate = date('Y-m-d', strtotime('+30 days'));
        $alerted = 0;
        $expired = 0;

        $docTypes = [
            'national_id'      => 'بطاقة الرقم القومي',
            'passport'         => 'جواز السفر',
            'degree'           => 'الشهادة الدراسية',
            'military_cert'    => 'شهادة الخدمة العسكرية',
            'insurance_form'   => 'نموذج التأمينات',
            'medical_report'   => 'التقرير الطبي',
            'criminal_record'  => 'الفيش الجنائي',
            'work_permit'      => 'تصريح العمل',
        ];

        // Documents expiring within 30 days
        $expiringDocs = $this->db->select(
            "SELECT d.id, d.employee_profile_id, d.document_type, d.expiry_date,
                    hp.first_name_ar, hp.last_name_ar, hp.employee_number,
                    DATEDIFF(d.expiry_date, ?) as days_remaining
             FROM hr_employee_documents d
             JOIN hr_employee_profiles hp ON hp.id = d.employee_profile_id
             WHERE d.expiry_date IS NOT NULL
               AND d.expiry_date >= ?
               AND d.expiry_date <= ?
               AND d.is_archived = 0
               AND hp.employment_status = 'active'
               AND hp.is_archived = 0",
            [$today, $today, $alertDate]
        );

        foreach ($expiringDocs as $doc) {
            $daysRemaining = (int) $doc['days_remaining'];
            $employeeName = $doc['first_name_ar'] . ' ' . $doc['last_name_ar'];
            $docTypeName = $docTypes[$doc['document_type']] ?? $doc['document_type'];

            // Only alert once per week (check if similar notification exists in last 7 days)
            $link = '/hr/documents/employee/' . (int) $doc['employee_profile_id'];
            $recentAlert = $this->db->selectOne(
                "SELECT id FROM notification_queue
                 WHERE data_json LIKE ?
                   AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)",
                ['%hr_document_expiry%' . $link . '%']
            );

            if (!$recentAlert) {
                $this->db->insert('notification_queue', [
                    'type'           => 'system',
                    'recipient_type' => 'employee',
                    'recipient_id'   => 0,
                    'subject'        => 'مستند قارب على الانتهاء',
                    'message'        => "{$docTypeName} للموظف {$employeeName} سينتهي خلال {$daysRemaining} يوم (تاريخ الانتهاء: {$doc['expiry_date']})",
                    'data_json'      => json_encode(['hr_type' => 'hr_document_expiry', 'link' => $link], JSON_UNESCAPED_UNICODE),
                    'status'         => 'pending',
                    'created_at'     => date('Y-m-d H:i:s'),
                ]);
                $alerted++;
            }
        }

        // Count already-expired documents for logging
        $expiredCount = $this->db->selectOne(
            "SELECT COUNT(*) as c FROM hr_employee_documents d
             JOIN hr_employee_profiles hp ON hp.id = d.employee_profile_id
             WHERE d.expiry_date IS NOT NULL
               AND d.expiry_date < ?
               AND d.is_archived = 0
               AND hp.employment_status = 'active'
               AND hp.is_archived = 0",
            [$today]
        );
        $expired = (int) ($expiredCount['c'] ?? 0);

        if ($alerted > 0) {
            Logger::info("HR Document Expiry Job: {$alerted} expiry alerts sent, {$expired} already expired");
        }

        return [
            'alerted'         => $alerted,
            'already_expired' => $expired,
        ];
    }
}
