<?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;
use App\Core\Pagination;
use App\Modules\Members\Services\NationalIdParser;
use App\Modules\Members\Services\MembershipValidationService;
use App\Modules\SportsActivity\Services\RegistrationWizardService;
use App\Modules\Carnets\Services\QRCodeGenerator;
use App\Modules\Settings\Services\BrandingService;

class RegistrationWizardController extends Controller
{
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();

        $recentRegistrations = $db->select(
            "SELECT r.*, p.full_name_ar, p.photo_path, g.name_ar as group_name
             FROM sa_registrations r
             INNER JOIN sa_players p ON p.id = r.player_id
             LEFT JOIN sa_groups g ON g.id = r.group_id
             WHERE r.status != 'cancelled'
             ORDER BY r.created_at DESC
             LIMIT 10"
        );

        return $this->view('SportsActivity.Views.registration.wizard', [
            'recentRegistrations' => $recentRegistrations,
        ]);
    }

    public function lookupPlayer(Request $request): Response
    {
        $nationalId = trim((string) $request->post('national_id', ''));
        $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;
        if ($nationalId !== '' && strlen($nationalId) === 14) {
            $nidParsed = NationalIdParser::parse($nationalId);
        }

        $playerType = 'non_member';
        $memberId = 0;
        $membershipReason = null;

        if ($nationalId !== '' && strlen($nationalId) === 14) {
            $membership = MembershipValidationService::checkByNationalId($nationalId);
            $playerType = $membership['effective_type'];
            $membershipReason = $membership['reason'];
            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'] ?? '');
            }
        }

        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(array_merge($result, [
            'nid_parsed'        => $nidParsed,
            'effective_type'    => $playerType,
            'membership_reason' => $membershipReason,
            'redirect'          => '/sa/registration/' . $result['registration_id'],
        ]));
    }

    public function wizardStep(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
             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/registration')->withError('التسجيل غير موجود');
        }

        $groups = $db->select(
            "SELECT g.*, p.name_ar as program_name, p.discipline_id, d.name_ar as discipline_name
             FROM sa_groups g
             LEFT JOIN sa_programs p ON p.id = g.program_id
             LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
             WHERE g.status = 'active' AND g.is_archived = 0 AND g.is_full = 0
             ORDER BY d.name_ar ASC, g.name_ar ASC"
        );

        $selectedGroup = null;
        if ($registration['group_id']) {
            $selectedGroup = $db->selectOne(
                "SELECT g.*, p.name_ar as program_name, d.name_ar as discipline_name
                 FROM sa_groups g
                 LEFT JOIN sa_programs p ON p.id = g.program_id
                 LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
                 WHERE g.id = ?",
                [(int) $registration['group_id']]
            );
        }

        return $this->view('SportsActivity.Views.registration.wizard', [
            'registration'  => $registration,
            'groups'        => $groups,
            'selectedGroup' => $selectedGroup,
            'step'          => $this->determineStep($registration),
        ]);
    }

    public function uploadPhoto(Request $request, string $id): Response
    {
        $registrationId = (int) $id;

        $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' => 'لم يتم رفع صورة']);
            }
        }

        $result = RegistrationWizardService::capturePhoto($registrationId, $file);
        return $this->json($result);
    }

    public function submitFormPayment(Request $request, string $id): Response
    {
        $registrationId = (int) $id;
        $result = RegistrationWizardService::submitFormPayment($registrationId);
        return $this->json($result);
    }

    public function selectActivity(Request $request, string $id): Response
    {
        $registrationId = (int) $id;
        $programId = (int) $request->post('program_id', 0);
        $groupId = (int) $request->post('group_id', 0);
        $months = max(1, (int) $request->post('months', 1));
        $hasSibling = (bool) $request->post('has_sibling', false);

        if ($programId > 0) {
            $result = RegistrationWizardService::selectProgram($registrationId, $programId, $months, $hasSibling);
        } elseif ($groupId > 0) {
            $result = RegistrationWizardService::selectGroup($registrationId, $groupId, $months, $hasSibling);
        } else {
            return $this->json(['success' => false, 'error' => 'اختر برنامج أو مجموعة']);
        }

        return $this->json($result);
    }

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

        $programs = $db->select(
            "SELECT p.id, p.name_ar, p.name_en, p.description_ar,
                    COUNT(g.id) as group_count,
                    MIN(g.monthly_fee_member) as min_fee_member,
                    MIN(g.monthly_fee_nonmember) as min_fee_nonmember
             FROM sa_programs p
             LEFT JOIN sa_groups g ON g.program_id = p.id AND g.status = 'active' AND g.is_archived = 0
             WHERE p.discipline_id = ? AND p.is_archived = 0
             GROUP BY p.id, p.name_ar, p.name_en, p.description_ar
             ORDER BY p.name_ar",
            [(int) $disciplineId]
        );

        return $this->json(['success' => true, 'programs' => $programs]);
    }

    public function getDisciplines(Request $request): Response
    {
        $db = App::getInstance()->db();

        $disciplines = $db->select(
            "SELECT d.id, d.name_ar, d.name_en, d.icon
             FROM sa_disciplines d
             WHERE d.is_active = 1 AND d.is_archived = 0
             ORDER BY d.name_ar"
        );

        return $this->json(['success' => true, 'disciplines' => $disciplines]);
    }

    public function submitPayment(Request $request, string $id): Response
    {
        $registrationId = (int) $id;
        $result = RegistrationWizardService::submitToPaymentQueue($registrationId);
        return $this->json($result);
    }

    public function printForm(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.guardian_name, p.guardian_phone, p.guardian_national_id, p.guardian_relationship,
                    p.registration_serial
             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/registration')->withError('التسجيل غير موجود');
        }

        $group = null;
        if ($registration['group_id']) {
            $group = $db->selectOne(
                "SELECT g.*, p.name_ar as program_name, d.name_ar as discipline_name
                 FROM sa_groups g
                 LEFT JOIN sa_programs p ON p.id = g.program_id
                 LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
                 WHERE g.id = ?",
                [(int) $registration['group_id']]
            );
        }

        $qrSvg = QRCodeGenerator::renderSvg(
            QRCodeGenerator::encode('SAR:' . $registration['registration_number']),
            120
        );

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

        return $this->view('SportsActivity.Views.registration.print_form', [
            'registration' => $registration,
            'group'        => $group,
            'qrSvg'        => $qrSvg,
        ]);
    }

    public function generateCard(Request $request, string $id): Response
    {
        $result = RegistrationWizardService::generateCard((int) $id);
        return $this->json($result);
    }

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

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

        $card = $db->selectOne(
            "SELECT c.*, p.full_name_ar, p.full_name_en, p.national_id, p.date_of_birth,
                    p.player_type, p.phone, p.photo_path as player_photo
             FROM sa_player_cards c
             INNER JOIN sa_players p ON p.id = c.player_id
             WHERE c.registration_id = ? AND c.is_archived = 0
             ORDER BY c.id DESC LIMIT 1",
            [(int) $id]
        );
        if (!$card) {
            return $this->redirect('/sa/registration/' . $id)->withError('لم يتم إنشاء الكارت بعد');
        }

        $group = null;
        if ($registration['group_id']) {
            $group = $db->selectOne(
                "SELECT g.name_ar, d.name_ar as discipline_name
                 FROM sa_groups g
                 LEFT JOIN sa_programs p ON p.id = g.program_id
                 LEFT JOIN sa_disciplines d ON d.id = p.discipline_id
                 WHERE g.id = ?",
                [(int) $registration['group_id']]
            );
        }

        $qrSvg = QRCodeGenerator::renderSvg($card['qr_code_data'] ?? '', 150);

        $db->update('sa_player_cards', [
            'print_count'    => (int) $card['print_count'] + 1,
            'last_printed_at' => date('Y-m-d H:i:s'),
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) $card['id']]);

        return $this->view('SportsActivity.Views.cards.print', [
            'card'  => $card,
            'group' => $group,
            'qrSvg' => $qrSvg,
        ]);
    }

    public function cancel(Request $request, string $id): Response
    {
        $reason = trim((string) $request->post('reason', ''));
        $result = RegistrationWizardService::cancelRegistration((int) $id, $reason);

        if (!$result['success']) {
            return $this->redirect('/sa/registration/' . $id)->withError($result['error']);
        }

        return $this->redirect('/sa/registration')->withSuccess('تم إلغاء التسجيل');
    }

    public function report(Request $request): Response
    {
        $db = App::getInstance()->db();

        $dateFrom = trim((string) $request->get('from', date('Y-m-01')));
        $dateTo = trim((string) $request->get('to', date('Y-m-d')));

        $summary = $db->selectOne(
            "SELECT
                COUNT(*) as total_registrations,
                SUM(CASE WHEN status = 'completed' THEN 1 ELSE 0 END) as completed,
                SUM(CASE WHEN status = 'cancelled' THEN 1 ELSE 0 END) as cancelled,
                SUM(CASE WHEN status = 'pending_payment' THEN 1 ELSE 0 END) as pending,
                SUM(CASE WHEN status = 'completed' THEN total_fees ELSE 0 END) as total_revenue,
                SUM(CASE WHEN player_type = 'member' AND status = 'completed' THEN 1 ELSE 0 END) as member_count,
                SUM(CASE WHEN player_type = 'non_member' AND status = 'completed' THEN 1 ELSE 0 END) as nonmember_count,
                SUM(CASE WHEN card_generated = 1 THEN 1 ELSE 0 END) as cards_issued,
                SUM(CASE WHEN form_printed = 1 THEN 1 ELSE 0 END) as forms_printed
             FROM sa_registrations
             WHERE DATE(created_at) BETWEEN ? AND ?",
            [$dateFrom, $dateTo]
        );

        $dailyBreakdown = $db->select(
            "SELECT DATE(created_at) as reg_date,
                    COUNT(*) as total,
                    SUM(CASE WHEN status = 'completed' THEN total_fees ELSE 0 END) as revenue
             FROM sa_registrations
             WHERE DATE(created_at) BETWEEN ? AND ?
             GROUP BY DATE(created_at)
             ORDER BY reg_date DESC",
            [$dateFrom, $dateTo]
        );

        return $this->view('SportsActivity.Views.registration.report', [
            'summary'        => $summary,
            'dailyBreakdown' => $dailyBreakdown,
            'dateFrom'       => $dateFrom,
            'dateTo'         => $dateTo,
        ]);
    }

    private function determineStep(array $registration): int
    {
        // Step 1: Pay form fee (استمارة اشتراك)
        // Step 2: Photo capture
        // Step 3: Select activity/group
        // Step 4: Pay subscription
        // Step 5: Complete (print/card)
        if ($registration['status'] === 'completed' || $registration['payment_status'] === 'paid') {
            return 5;
        }
        if ($registration['status'] === 'pending_payment') {
            return 4;
        }
        if (!empty($registration['group_id'])) {
            return 4;
        }
        if ((int) $registration['photo_captured'] === 1) {
            return 3;
        }
        $formPaid = ($registration['form_payment_status'] ?? 'unpaid') === 'paid';
        if ($formPaid) {
            return 2;
        }
        return 1;
    }

    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;
        }

        $tmpFile = tempnam(sys_get_temp_dir(), 'sa_photo_');
        if ($tmpFile === false) {
            return null;
        }

        file_put_contents($tmpFile, $decoded);

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