<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Controllers;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;

class PlayerDocumentController extends Controller
{
    /**
     * List documents for a player.
     */
    public function index(Request $request, string $pid): Response
    {
        $db = App::getInstance()->db();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $documents = $db->select(
            "SELECT * FROM sa_player_documents WHERE player_id = ? ORDER BY created_at DESC",
            [(int) $pid]
        );

        return $this->view('SportsActivity.Views.players.documents', [
            'player'    => $player,
            'documents' => $documents,
        ]);
    }

    /**
     * Handle file upload for a player document.
     */
    public function upload(Request $request, string $pid): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $documentType = trim((string) $request->post('document_type', ''));

        // Validation
        $errors = [];
        if ($documentType === '') {
            $errors[] = 'نوع المستند مطلوب';
        }

        $file = $_FILES['document_file'] ?? null;
        if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
            $errors[] = 'الملف مطلوب';
        }

        if (!empty($errors)) {
            $session->flash('_alerts', array_map(fn($e) => ['type' => 'error', 'message' => $e], $errors));
            return $this->redirect('/sa/players/' . $pid . '/documents');
        }

        // Upload file
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        $newName = uniqid('doc_') . '.' . $ext;
        $uploadDir = dirname(__DIR__, 4) . '/public/uploads/sa_documents/';

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

        $dest = $uploadDir . $newName;
        move_uploaded_file($file['tmp_name'], $dest);

        $filePath = 'uploads/sa_documents/' . $newName;

        $data = [
            'player_id'       => (int) $pid,
            'document_type'   => $documentType,
            'file_path'       => $filePath,
            'file_name'       => $file['name'],
            'approval_status' => 'pending',
            'created_by'      => (int) (App::getInstance()->session()->get('employee_id') ?? 0),
            'created_at'      => now(),
            'updated_at'      => now(),
        ];

        $db->insert('sa_player_documents', $data);
        $docId = (int) $db->lastInsertId();

        if ($documentType === 'medical_cert') {
            $db->insert('player_medical_records', [
                'player_id'       => null,
                'sa_player_id'    => (int) $pid,
                'record_type'     => 'fitness_cert',
                'sa_document_id'  => $docId,
                'approval_status' => 'pending',
                'source'          => 'sports_activity',
                'created_by'      => (int) (App::getInstance()->session()->get('employee_id') ?? 0),
                'created_at'      => now(),
                'updated_at'      => now(),
            ]);
        }

        return $this->redirect('/sa/players/' . $pid . '/documents')->withSuccess('تم رفع المستند بنجاح' . ($documentType === 'medical_cert' ? ' — تم إرساله للجنة الطبية للمراجعة' : ''));
    }

    /**
     * Approve a document (medical certificate).
     * Sets approval_status='approved', updates player medical_status='fit' with expiry_date.
     */
    public function approve(Request $request, string $pid, string $id): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $document = $db->selectOne(
            "SELECT * FROM sa_player_documents WHERE id = ? AND player_id = ?",
            [(int) $id, (int) $pid]
        );
        if (!$document) {
            return $this->redirect('/sa/players/' . $pid . '/documents')->withError('المستند غير موجود');
        }

        $expiryDate = trim((string) $request->post('expiry_date', ''));
        if ($expiryDate === '') {
            $session->flash('_alerts', [['type' => 'error', 'message' => 'تاريخ انتهاء الصلاحية مطلوب']]);
            return $this->redirect('/sa/players/' . $pid . '/documents');
        }

        // Update document
        $db->update('sa_player_documents', [
            'approval_status' => 'approved',
            'approved_by'     => (int) ($session->get('employee_id') ?? 0),
            'approved_at'     => now(),
            'expiry_date'     => $expiryDate,
            'updated_at'      => now(),
        ], 'id = ?', [(int) $id]);

        // Update player medical status
        $db->update('sa_players', [
            'medical_status'      => 'fit',
            'medical_expiry_date' => $expiryDate,
            'updated_at'          => now(),
        ], 'id = ?', [(int) $pid]);

        return $this->redirect('/sa/players/' . $pid . '/documents')->withSuccess('تم اعتماد المستند وتحديث الحالة الطبية');
    }

    /**
     * Reject a document.
     * Sets approval_status='rejected', updates player medical_status='unfit'.
     */
    public function reject(Request $request, string $pid, string $id): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $document = $db->selectOne(
            "SELECT * FROM sa_player_documents WHERE id = ? AND player_id = ?",
            [(int) $id, (int) $pid]
        );
        if (!$document) {
            return $this->redirect('/sa/players/' . $pid . '/documents')->withError('المستند غير موجود');
        }

        $rejectionReason = trim((string) $request->post('rejection_reason', ''));
        if ($rejectionReason === '') {
            $session->flash('_alerts', [['type' => 'error', 'message' => 'سبب الرفض مطلوب']]);
            return $this->redirect('/sa/players/' . $pid . '/documents');
        }

        // Update document
        $db->update('sa_player_documents', [
            'approval_status'  => 'rejected',
            'rejection_reason' => $rejectionReason,
            'approved_by'      => (int) ($session->get('employee_id') ?? 0),
            'approved_at'      => now(),
            'updated_at'       => now(),
        ], 'id = ?', [(int) $id]);

        // Update player medical status
        $db->update('sa_players', [
            'medical_status' => 'unfit',
            'updated_at'     => now(),
        ], 'id = ?', [(int) $pid]);

        return $this->redirect('/sa/players/' . $pid . '/documents')->withSuccess('تم رفض المستند');
    }

    /**
     * Approve a medical document with conditional status.
     */
    public function approveConditional(Request $request, string $pid, string $id): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $document = $db->selectOne(
            "SELECT * FROM sa_player_documents WHERE id = ? AND player_id = ?",
            [(int) $id, (int) $pid]
        );
        if (!$document) {
            return $this->redirect('/sa/players/' . $pid . '/documents')->withError('المستند غير موجود');
        }

        $expiryDate = trim((string) $request->post('expiry_date', ''));
        $conditionalNotes = trim((string) $request->post('conditional_notes', ''));

        if ($expiryDate === '') {
            return $this->redirect('/sa/players/' . $pid . '/documents')->withError('تاريخ انتهاء الصلاحية مطلوب');
        }
        if ($conditionalNotes === '') {
            return $this->redirect('/sa/players/' . $pid . '/documents')->withError('ملاحظات الاعتماد المشروط مطلوبة');
        }

        $db->update('sa_player_documents', [
            'approval_status'   => 'approved',
            'conditional_notes' => $conditionalNotes,
            'approved_by'       => (int) ($session->get('employee_id') ?? 0),
            'approved_at'       => now(),
            'expiry_date'       => $expiryDate,
            'updated_at'        => now(),
        ], 'id = ?', [(int) $id]);

        $db->update('sa_players', [
            'medical_status'      => 'conditional',
            'medical_expiry_date' => $expiryDate,
            'updated_at'          => now(),
        ], 'id = ?', [(int) $pid]);

        return $this->redirect('/sa/players/' . $pid . '/documents')->withSuccess('تم الاعتماد المشروط وتحديث الحالة الطبية');
    }

    /**
     * Update medical details directly from player screen.
     */
    public function updateMedical(Request $request, string $pid): Response
    {
        $db = App::getInstance()->db();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $pid]);
        if (!$player) {
            return $this->redirect('/sa/players')->withError('اللاعب غير موجود');
        }

        $medicalStatus = trim((string) $request->post('medical_status', ''));
        $expiryDate = trim((string) $request->post('medical_expiry_date', ''));
        $doctorName = trim((string) $request->post('doctor_name', ''));
        $clinicName = trim((string) $request->post('clinic_name', ''));
        $examDate = trim((string) $request->post('exam_date', ''));

        $validStatuses = ['pending', 'fit', 'conditional', 'unfit', 'expired'];
        if (!in_array($medicalStatus, $validStatuses, true)) {
            return $this->redirect('/sa/players/' . $pid)->withError('حالة طبية غير صالحة');
        }

        $db->update('sa_players', [
            'medical_status'      => $medicalStatus,
            'medical_expiry_date' => $expiryDate ?: null,
            'updated_at'          => now(),
        ], 'id = ?', [(int) $pid]);

        $latestDoc = $db->selectOne(
            "SELECT id FROM sa_player_documents WHERE player_id = ? AND document_type = 'medical_cert' ORDER BY created_at DESC LIMIT 1",
            [(int) $pid]
        );

        if ($latestDoc) {
            $docUpdate = ['updated_at' => now()];
            if ($examDate !== '') $docUpdate['exam_date'] = $examDate;
            if ($expiryDate !== '') $docUpdate['expiry_date'] = $expiryDate;
            if ($doctorName !== '') $docUpdate['doctor_name'] = $doctorName;
            if ($clinicName !== '') $docUpdate['clinic_name'] = $clinicName;

            if (in_array($medicalStatus, ['fit', 'conditional'], true)) {
                $docUpdate['approval_status'] = 'approved';
                $docUpdate['approved_by'] = (int) (App::getInstance()->session()->get('employee_id') ?? 0);
                $docUpdate['approved_at'] = now();
            } elseif ($medicalStatus === 'unfit') {
                $docUpdate['approval_status'] = 'rejected';
            }

            $db->update('sa_player_documents', $docUpdate, 'id = ?', [(int) $latestDoc['id']]);
        }

        return $this->redirect('/sa/players/' . $pid)->withSuccess('تم تحديث البيانات الطبية');
    }
}
