<?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\HrEmployeeDocument;
use App\Modules\HR\Models\HrEmployeeProfile;

class EmployeeDocumentController extends Controller
{
    public function index(Request $request): Response
    {
        $filters = [
            'q'               => trim((string) $request->get('q', '')),
            'document_type'   => trim((string) $request->get('document_type', '')),
            'expiring_soon'   => trim((string) $request->get('expiring_soon', '')),
            'validity_status' => trim((string) $request->get('validity_status', '')),
        ];

        // Auto-update validity statuses before displaying
        $this->updateValidityStatuses();

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

        return $this->view('HR.Views.documents.index', [
            'documents'     => $result['data'],
            'pagination'    => $result['pagination'],
            'filters'       => $filters,
            'documentTypes' => HrEmployeeDocument::getDocumentTypes(),
        ]);
    }

    private function updateValidityStatuses(): void
    {
        $db = App::getInstance()->db();
        $today = date('Y-m-d');
        $soonDate = date('Y-m-d', strtotime('+30 days'));

        // Mark expired documents
        $db->query(
            "UPDATE hr_employee_documents SET validity_status = 'expired'
             WHERE expiry_date IS NOT NULL AND expiry_date < ? AND is_archived = 0",
            [$today]
        );

        // Mark expiring soon (within 30 days)
        $db->query(
            "UPDATE hr_employee_documents SET validity_status = 'expiring_soon'
             WHERE expiry_date IS NOT NULL AND expiry_date >= ? AND expiry_date <= ? AND is_archived = 0",
            [$today, $soonDate]
        );

        // Mark valid (expiry date more than 30 days away)
        $db->query(
            "UPDATE hr_employee_documents SET validity_status = 'valid'
             WHERE expiry_date IS NOT NULL AND expiry_date > ? AND is_archived = 0",
            [$soonDate]
        );
    }

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

        $db = App::getInstance()->db();
        $documents = $db->select(
            "SELECT * FROM hr_employee_documents WHERE employee_profile_id = ? AND is_archived = 0 ORDER BY created_at DESC",
            [(int) $employeeId]
        );

        return $this->view('HR.Views.documents.by_employee', [
            'profile'       => $profile,
            'documents'     => $documents,
            'documentTypes' => HrEmployeeDocument::getDocumentTypes(),
        ]);
    }

    public function upload(Request $request): Response
    {
        $profileId = (int) $request->post('employee_profile_id', 0);
        $documentType = trim((string) $request->post('document_type', ''));
        $titleAr = trim((string) $request->post('title_ar', '')) ?: null;
        $expiryDate = trim((string) $request->post('expiry_date', '')) ?: null;
        $notes = trim((string) $request->post('notes', '')) ?: null;

        $errors = [];
        if ($profileId <= 0) {
            $errors[] = 'الموظف غير محدد';
        }
        if ($documentType === '') {
            $errors[] = 'نوع المستند مطلوب';
        }

        // File is required (NOT NULL columns depend on it)
        if (!isset($_FILES['document_file']) || $_FILES['document_file']['error'] !== UPLOAD_ERR_OK) {
            $errors[] = 'يجب رفع ملف';
        }

        // Handle file upload
        $filePath = null;
        $originalFilename = '';
        $storedFilename = '';
        $fileSize = 0;
        $mimeType = '';
        if (isset($_FILES['document_file']) && $_FILES['document_file']['error'] === UPLOAD_ERR_OK) {
            $allowedTypes = ['application/pdf', 'image/jpeg', 'image/png', 'image/jpg'];
            $mimeType = $_FILES['document_file']['type'];
            $fileSize = (int) $_FILES['document_file']['size'];
            $originalFilename = $_FILES['document_file']['name'];

            if (!in_array($mimeType, $allowedTypes, true)) {
                $errors[] = 'نوع الملف غير مسموح. المسموح: PDF, JPEG, PNG';
            }
            if ($fileSize > 5 * 1024 * 1024) {
                $errors[] = 'حجم الملف يجب أن يكون أقل من 5 ميجابايت';
            }

            if (empty($errors)) {
                $uploadDir = 'uploads/hr/documents/' . $profileId;
                $absUploadDir = rtrim($_SERVER['DOCUMENT_ROOT'] ?? '', '/') . '/' . $uploadDir;

                if (!is_dir($absUploadDir)) {
                    mkdir($absUploadDir, 0755, true);
                }

                $ext = pathinfo($originalFilename, PATHINFO_EXTENSION);
                $storedFilename = $documentType . '_' . date('Ymd_His') . '.' . $ext;
                $targetPath = $absUploadDir . '/' . $storedFilename;

                if (move_uploaded_file($_FILES['document_file']['tmp_name'], $targetPath)) {
                    $filePath = $uploadDir . '/' . $storedFilename;
                } else {
                    $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/documents/employee/' . $profileId);
        }

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

        $docId = $db->insert('hr_employee_documents', [
            'employee_profile_id' => $profileId,
            'document_type'       => $documentType,
            'title_ar'            => $titleAr ?: ($docTypes[$documentType] ?? $documentType),
            'original_filename'   => $originalFilename,
            'stored_filename'     => $storedFilename,
            'file_path'           => $filePath,
            'file_size'           => $fileSize,
            'mime_type'           => $mimeType,
            'expiry_date'         => $expiryDate,
            'notes'               => $notes,
            'is_verified'         => 0,
            'uploaded_by'         => $employee ? (int) $employee->id : null,
            '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,
        ]);

        Logger::info("Document uploaded", ['document_id' => $docId, 'profile_id' => $profileId, 'type' => $documentType]);

        return $this->redirect('/hr/documents/employee/' . $profileId)->withSuccess('تم رفع المستند بنجاح');
    }

    public function verify(Request $request, string $id): Response
    {
        $document = HrEmployeeDocument::find((int) $id);
        if (!$document) {
            return $this->redirect('/hr/documents')->withError('المستند غير موجود');
        }

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

        $db->update('hr_employee_documents', [
            'is_verified'  => 1,
            'verified_by'  => $employee ? (int) $employee->id : null,
            'verified_at'  => date('Y-m-d H:i:s'),
            'updated_at'   => date('Y-m-d H:i:s'),
        ], '`id` = ?', [(int) $id]);

        return $this->redirect('/hr/documents/employee/' . $document->employee_profile_id)->withSuccess('تم التحقق من المستند');
    }

    public function archive(Request $request, string $id): Response
    {
        $document = HrEmployeeDocument::find((int) $id);
        if (!$document) {
            return $this->redirect('/hr/documents')->withError('المستند غير موجود');
        }

        $profileId = $document->employee_profile_id;
        $document->archive();

        return $this->redirect('/hr/documents/employee/' . $profileId)->withSuccess('تم حذف المستند');
    }
}
