<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Controllers\Swimming;

use App\Core\Controller;
use App\Core\Request;
use App\Core\Response;
use App\Core\App;
use App\Modules\Members\Services\NationalIdParser;
use App\Modules\Members\Services\MembershipValidationService;
use App\Modules\SportsActivity\Services\RegistrationWizardService;
use App\Shared\Services\PhotoUploadService;

class SwimmingRegistrationController extends Controller
{
    public function index(Request $request): Response
    {
        return $this->view('SportsActivity.Views.swimming.register', [
            'registration' => null,
            'step'         => 'lookup',
        ]);
    }

    public function lookup(Request $request): Response
    {
        $nationalId = trim((string) $request->post('national_id', ''));
        $membershipNumber = trim((string) $request->post('membership_number', ''));
        $fullNameAr = trim((string) $request->post('full_name_ar', ''));
        $fullNameEn = trim((string) $request->post('full_name_en', ''));
        $phone = trim((string) $request->post('phone', ''));
        $guardianName = trim((string) $request->post('guardian_name', ''));
        $guardianPhone = trim((string) $request->post('guardian_phone', ''));
        $guardianNationalId = trim((string) $request->post('guardian_national_id', ''));
        $guardianRelationship = trim((string) $request->post('guardian_relationship', ''));

        $nidParsed = null;
        $playerType = 'non_member';
        $memberId = 0;
        $membership = null;

        if ($membershipNumber !== '') {
            $membership = MembershipValidationService::checkByMembershipNumber($membershipNumber);
        } elseif ($nationalId !== '' && strlen($nationalId) === 14) {
            $nidParsed = NationalIdParser::parse($nationalId);
            $membership = MembershipValidationService::checkByNationalId($nationalId);
        }

        if ($membership) {
            $playerType = $membership['effective_type'];
            if ($membership['found'] && $membership['member']) {
                $memberId = (int) $membership['member_id'];
                $m = $membership['member'];
                $fullNameAr = $fullNameAr ?: ($m['full_name_ar'] ?? '');
                $fullNameEn = $fullNameEn ?: ($m['full_name_en'] ?? '');
                $phone = $phone ?: ($m['phone_mobile'] ?? '');
                $nationalId = $nationalId ?: ($m['national_id'] ?? '');
                if ($nationalId !== '' && strlen($nationalId) === 14 && !$nidParsed) {
                    $nidParsed = NationalIdParser::parse($nationalId);
                }
            }
        }

        if ($fullNameAr === '' && $nidParsed === null) {
            return $this->json(['success' => false, 'error' => 'أدخل رقم العضوية أو الرقم القومي أو الاسم']);
        }

        $result = RegistrationWizardService::startRegistration([
            'national_id'           => $nationalId,
            'player_type'           => $playerType,
            'member_id'             => $memberId,
            'full_name_ar'          => $fullNameAr,
            'full_name_en'          => $fullNameEn,
            'date_of_birth'         => $nidParsed['dob'] ?? null,
            'gender'                => $nidParsed['gender'] ?? null,
            'phone'                 => $phone,
            'guardian_name'         => $guardianName,
            'guardian_phone'        => $guardianPhone,
            'guardian_national_id'  => $guardianNationalId,
            'guardian_relationship' => $guardianRelationship,
        ]);

        if (!$result['success']) {
            return $this->json($result);
        }

        return $this->json([
            'success'         => true,
            'registration_id' => $result['registration_id'],
            'player_id'       => $result['player_id'],
            'nid_parsed'      => $nidParsed,
            'effective_type'  => $playerType,
            'redirect'        => '/sa/swimming/register/' . $result['registration_id'],
        ]);
    }

    public function step(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $registration = $db->selectOne(
            "SELECT r.*, p.full_name_ar, p.full_name_en, p.national_id as player_nid,
                    p.date_of_birth, p.gender, p.phone, p.photo_path, p.player_type as p_type,
                    p.guardian_name, p.guardian_phone, p.guardian_national_id, p.guardian_relationship,
                    p.medical_status, p.id as player_id
             FROM sa_registrations r
             INNER JOIN sa_players p ON p.id = r.player_id
             WHERE r.id = ?",
            [(int) $id]
        );

        if (!$registration) {
            return $this->redirect('/sa/swimming/register')->withError('التسجيل غير موجود');
        }

        $hasMedical = (bool) $db->selectOne(
            "SELECT 1 FROM sa_player_documents WHERE player_id = ? AND document_type = 'medical_cert'",
            [(int) $registration['player_id']]
        );

        $currentStep = 'personal';
        if ($registration['status'] !== 'in_progress') {
            $currentStep = 'complete';
        } elseif ($hasMedical && $registration['photo_captured']) {
            $currentStep = 'complete';
        } elseif ($hasMedical) {
            $currentStep = 'photo';
        } else {
            $currentStep = 'medical';
        }

        return $this->view('SportsActivity.Views.swimming.register', [
            'registration' => $registration,
            'step'         => $currentStep,
            'hasMedical'   => $hasMedical,
        ]);
    }

    public function saveMedical(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $registration = $db->selectOne(
            "SELECT r.*, p.id as player_id FROM sa_registrations r
             INNER JOIN sa_players p ON p.id = r.player_id
             WHERE r.id = ? AND r.status = 'in_progress'",
            [(int) $id]
        );
        if (!$registration) {
            return $this->json(['success' => false, 'error' => 'التسجيل غير موجود أو مكتمل']);
        }

        $file = $_FILES['medical_file'] ?? null;
        if (!$file || $file['error'] !== UPLOAD_ERR_OK) {
            return $this->json(['success' => false, 'error' => 'الشهادة الطبية مطلوبة']);
        }

        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (!in_array($ext, ['pdf', 'png', 'jpg', 'jpeg'])) {
            return $this->json(['success' => false, 'error' => 'صيغة الملف غير مدعومة (PDF, PNG, JPG فقط)']);
        }

        $maxSize = 10 * 1024 * 1024;
        if ($file['size'] > $maxSize) {
            return $this->json(['success' => false, 'error' => 'حجم الملف يتجاوز 10 ميجابايت']);
        }

        $examDate = trim((string) $request->post('exam_date', ''));
        $expiryDate = trim((string) $request->post('expiry_date', ''));

        if ($examDate === '' || $expiryDate === '') {
            return $this->json(['success' => false, 'error' => 'تاريخ الفحص وتاريخ الانتهاء مطلوبان']);
        }

        $newName = uniqid('med_') . '.' . $ext;
        $uploadDir = dirname(__DIR__, 5) . '/public/uploads/sa_documents/';
        if (!is_dir($uploadDir)) {
            mkdir($uploadDir, 0755, true);
        }
        move_uploaded_file($file['tmp_name'], $uploadDir . $newName);
        $filePath = 'uploads/sa_documents/' . $newName;

        $playerId = (int) $registration['player_id'];
        $employeeId = (int) (App::getInstance()->session()->get('employee_id') ?? 0);

        $docId = $db->insert('sa_player_documents', [
            'player_id'       => $playerId,
            'document_type'   => 'medical_cert',
            'file_path'       => $filePath,
            'file_name'       => $file['name'],
            'exam_date'       => $examDate,
            'expiry_date'     => $expiryDate,
            'approval_status' => 'pending',
            'created_by'      => $employeeId,
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        $db->insert('player_medical_records', [
            'player_id'       => null,
            'sa_player_id'    => $playerId,
            'record_type'     => 'fitness_cert',
            'sa_document_id'  => $docId,
            'exam_date'       => $examDate,
            'expiry_date'     => $expiryDate,
            'approval_status' => 'pending',
            'source'          => 'sports_activity',
            'created_by'      => $employeeId,
            'created_at'      => date('Y-m-d H:i:s'),
            'updated_at'      => date('Y-m-d H:i:s'),
        ]);

        $db->update('sa_players', [
            'medical_status'      => 'pending',
            'medical_expiry_date' => $expiryDate,
            'updated_at'          => date('Y-m-d H:i:s'),
        ], 'id = ?', [$playerId]);

        return $this->json([
            'success'     => true,
            'document_id' => $docId,
            'redirect'    => '/sa/swimming/register/' . $id,
        ]);
    }

    public function savePhoto(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $registration = $db->selectOne(
            "SELECT r.*, p.id as player_id FROM sa_registrations r
             INNER JOIN sa_players p ON p.id = r.player_id
             WHERE r.id = ? AND r.status = 'in_progress'",
            [(int) $id]
        );
        if (!$registration) {
            return $this->json(['success' => false, 'error' => 'التسجيل غير موجود أو مكتمل']);
        }

        $base64 = trim((string) $request->post('photo_base64', ''));
        if ($base64 !== '') {
            $file = $this->base64ToTempFile($base64);
            if (!$file) {
                return $this->json(['success' => false, 'error' => 'فشل معالجة الصورة']);
            }
        } else {
            $file = $_FILES['photo'] ?? [];
            if (empty($file['tmp_name']) || $file['error'] !== UPLOAD_ERR_OK) {
                return $this->json(['success' => false, 'error' => 'لم يتم رفع صورة']);
            }
        }

        $playerId = (int) $registration['player_id'];
        $result = PhotoUploadService::upload($file, 'sa_players', $playerId);
        if (!$result) {
            return $this->json(['success' => false, 'error' => 'فشل رفع الصورة']);
        }

        $db->update('sa_players', [
            'photo_path' => $result['path'],
            'updated_at' => date('Y-m-d H:i:s'),
        ], 'id = ?', [$playerId]);

        $db->update('sa_registrations', [
            'photo_captured' => 1,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $id]);

        return $this->json([
            'success'    => true,
            'photo_path' => $result['path'],
            'redirect'   => '/sa/swimming/assign/' . $id,
        ]);
    }

    private function base64ToTempFile(string $base64): ?array
    {
        if (str_contains($base64, ',')) {
            $base64 = explode(',', $base64, 2)[1];
        }
        $decoded = base64_decode($base64, true);
        if ($decoded === false || strlen($decoded) < 100) {
            return null;
        }

        $tmp = tempnam(sys_get_temp_dir(), 'photo_');
        file_put_contents($tmp, $decoded);

        return [
            'tmp_name' => $tmp,
            'error'    => UPLOAD_ERR_OK,
            'size'     => strlen($decoded),
            'name'     => 'capture.jpg',
            'type'     => 'image/jpeg',
        ];
    }
}
