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

class PlayerController extends Controller
{
    /**
     * List players with search, filters, and pagination.
     */
    public function index(Request $request): Response
    {
        $db = App::getInstance()->db();

        $search = trim((string) $request->get('q', ''));
        $playerType = trim((string) $request->get('player_type', ''));
        $medicalStatus = trim((string) $request->get('medical_status', ''));
        $page = max(1, (int) $request->get('page', 1));
        $perPage = 25;

        $where = ['1=1'];
        $params = [];

        if ($search !== '') {
            $where[] = '(p.full_name_ar LIKE ? OR p.national_id LIKE ? OR p.registration_serial LIKE ?)';
            $params[] = "%{$search}%";
            $params[] = "%{$search}%";
            $params[] = "%{$search}%";
        }

        if ($playerType !== '') {
            $where[] = 'p.player_type = ?';
            $params[] = $playerType;
        }

        if ($medicalStatus !== '') {
            $where[] = 'p.medical_status = ?';
            $params[] = $medicalStatus;
        }

        $whereSql = implode(' AND ', $where);

        // Count total
        $countSql = "SELECT COUNT(*) as total FROM sa_players p WHERE {$whereSql}";
        $total = (int) $db->selectOne($countSql, $params)['total'];

        $pagination = Pagination::paginate($total, $perPage, $page);
        $offset = ($pagination['current_page'] - 1) * $perPage;

        // Fetch players
        $sql = "SELECT p.* FROM sa_players p WHERE {$whereSql} ORDER BY p.created_at DESC LIMIT {$perPage} OFFSET {$offset}";
        $players = $db->select($sql, $params);

        return $this->view('SportsActivity.Views.players.index', [
            'players'    => $players,
            'pagination' => $pagination,
            'filters'    => [
                'q'              => $search,
                'player_type'    => $playerType,
                'medical_status' => $medicalStatus,
            ],
        ]);
    }

    /**
     * Show the create player form.
     */
    public function create(Request $request): Response
    {
        return $this->view('SportsActivity.Views.players.create', []);
    }

    /**
     * Validate and store a new player.
     */
    public function store(Request $request): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

        $fullNameAr = trim((string) $request->post('full_name_ar', ''));
        $fullNameEn = trim((string) $request->post('full_name_en', ''));
        $playerType = trim((string) $request->post('player_type', ''));
        $memberId = (int) $request->post('member_id', 0);
        $nationalId = trim((string) $request->post('national_id', ''));
        $dateOfBirth = trim((string) $request->post('date_of_birth', ''));
        $gender = trim((string) $request->post('gender', 'male'));
        $phone = trim((string) $request->post('phone', ''));
        $email = trim((string) $request->post('email', ''));
        $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', ''));
        $notes = trim((string) $request->post('notes', ''));

        // For members: auto-fill from member record
        if ($playerType === 'member' && $memberId > 0) {
            $member = $db->selectOne(
                "SELECT full_name_ar, national_id, date_of_birth, gender FROM members WHERE membership_number = ? AND is_archived = 0",
                [$memberId]
            );
            if (!$member) {
                $member = $db->selectOne(
                    "SELECT full_name_ar, national_id, date_of_birth, gender FROM members WHERE id = ? AND is_archived = 0",
                    [$memberId]
                );
            }
            if ($member) {
                if ($fullNameAr === '') {
                    $fullNameAr = $member['full_name_ar'] ?? '';
                }
                if ($member['national_id']) {
                    $nationalId = $member['national_id'];
                }
                if ($member['date_of_birth']) {
                    $dateOfBirth = $member['date_of_birth'];
                }
                if ($member['gender']) {
                    $gender = $member['gender'];
                }
            }
        } elseif ($nationalId !== '' && strlen($nationalId) === 14) {
            $parsed = NationalIdParser::parse($nationalId);
            if ($parsed['is_valid']) {
                $dateOfBirth = $parsed['dob'];
                $gender = $parsed['gender'];
            }
        }

        // Validation
        $errors = [];
        if ($fullNameAr === '') {
            $errors[] = 'الاسم بالعربي مطلوب';
        } elseif (mb_strlen($fullNameAr) > 300) {
            $errors[] = 'الاسم بالعربي يجب ألا يتجاوز 300 حرف';
        }
        if ($playerType === '') {
            $errors[] = 'نوع اللاعب مطلوب';
        }
        if ($playerType === 'member' && $memberId <= 0) {
            $errors[] = 'رقم العضوية مطلوب للأعضاء';
        }

        $validTypes = ['member', 'non_member'];
        if ($playerType !== '' && !in_array($playerType, $validTypes, true)) {
            $errors[] = 'نوع اللاعب غير صالح';
        }

        if ($fullNameEn !== '' && mb_strlen($fullNameEn) > 300) {
            $errors[] = 'الاسم بالإنجليزي يجب ألا يتجاوز 300 حرف';
        }
        if ($nationalId !== '' && strlen($nationalId) > 14) {
            $errors[] = 'الرقم القومي يجب ألا يتجاوز 14 رقم';
        }
        if ($phone !== '' && mb_strlen($phone) > 30) {
            $errors[] = 'رقم الهاتف يجب ألا يتجاوز 30 حرف';
        }
        if ($email !== '' && mb_strlen($email) > 200) {
            $errors[] = 'البريد الإلكتروني يجب ألا يتجاوز 200 حرف';
        }
        if ($guardianName !== '' && mb_strlen($guardianName) > 300) {
            $errors[] = 'اسم ولي الأمر يجب ألا يتجاوز 300 حرف';
        }
        if ($guardianPhone !== '' && mb_strlen($guardianPhone) > 30) {
            $errors[] = 'هاتف ولي الأمر يجب ألا يتجاوز 30 حرف';
        }
        if ($guardianNationalId !== '' && strlen($guardianNationalId) > 14) {
            $errors[] = 'الرقم القومي لولي الأمر يجب ألا يتجاوز 14 رقم';
        }
        if ($guardianRelationship !== '' && mb_strlen($guardianRelationship) > 50) {
            $errors[] = 'صلة القرابة يجب ألا تتجاوز 50 حرف';
        }

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

        // Generate registration serial
        $maxSerial = $db->selectOne(
            "SELECT MAX(CAST(SUBSTRING(registration_serial, 5) AS UNSIGNED)) as max_num FROM sa_players WHERE registration_serial LIKE 'SAP-%'"
        );
        $nextNum = ((int) ($maxSerial['max_num'] ?? 0)) + 1;
        $serialNumber = 'SAP-' . str_pad((string) $nextNum, 5, '0', STR_PAD_LEFT);

        $data = [
            'registration_serial'  => $serialNumber,
            'full_name_ar'         => $fullNameAr,
            'full_name_en'         => $fullNameEn ?: null,
            'player_type'          => $playerType,
            'member_id'            => $memberId > 0 ? $memberId : null,
            'national_id'          => $nationalId ?: null,
            'date_of_birth'        => $dateOfBirth ?: null,
            'gender'               => $gender,
            'phone'                => $phone ?: null,
            'email'                => $email ?: null,
            'guardian_name'        => $guardianName ?: null,
            'guardian_phone'       => $guardianPhone ?: null,
            'guardian_national_id' => $guardianNationalId ?: null,
            'guardian_relationship' => $guardianRelationship ?: null,
            'medical_status'       => 'pending',
            'card_status'          => 'inactive',
            'notes'                => $notes ?: null,
            'created_at'           => now(),
            'updated_at'           => now(),
        ];

        $db->insert('sa_players', $data);
        $playerId = (int) $db->selectOne("SELECT LAST_INSERT_ID() as id")['id'];

        return $this->redirect('/sa/players/' . $playerId)->withSuccess('تم إضافة اللاعب بنجاح');
    }

    /**
     * Show player detail with documents list.
     */
    public function show(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

        $player = $db->selectOne("SELECT * FROM sa_players WHERE id = ?", [(int) $id]);
        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) $id]
        );

        $medicalHistory = $db->select(
            "SELECT * FROM sa_player_documents WHERE player_id = ? AND document_type = 'medical_cert' ORDER BY created_at DESC",
            [(int) $id]
        );

        $employee = App::getInstance()->currentEmployee();
        $canApproveMedical = $employee && method_exists($employee, 'hasPermission') && $employee->hasPermission('sa.medical.approve');

        $unpaidSubs = $db->select(
            "SELECT s.*, g.name_ar as group_name
             FROM sa_subscriptions s
             LEFT JOIN sa_groups g ON g.id = s.group_id
             WHERE s.player_id = ? AND s.payment_status IN ('unpaid', 'overdue', 'partial')
             ORDER BY s.period_start DESC",
            [(int) $id]
        );

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

    /**
     * Show edit form for a player.
     */
    public function edit(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();

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

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

    /**
     * Validate and update a player.
     */
    public function update(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $session = App::getInstance()->session();

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

        $fullNameAr = trim((string) $request->post('full_name_ar', ''));
        $fullNameEn = trim((string) $request->post('full_name_en', ''));
        $playerType = trim((string) $request->post('player_type', ''));
        $memberId = (int) $request->post('member_id', 0);
        $nationalId = trim((string) $request->post('national_id', ''));
        $dateOfBirth = trim((string) $request->post('date_of_birth', ''));
        $gender = trim((string) $request->post('gender', 'male'));
        $phone = trim((string) $request->post('phone', ''));
        $email = trim((string) $request->post('email', ''));
        $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', ''));
        $notes = trim((string) $request->post('notes', ''));

        // Auto-extract DOB and gender from national ID
        if ($nationalId !== '' && strlen($nationalId) === 14) {
            $parsed = NationalIdParser::parse($nationalId);
            if ($parsed['is_valid']) {
                $dateOfBirth = $parsed['dob'];
                $gender = $parsed['gender'];
            }
        }

        // Validation
        $errors = [];
        if ($fullNameAr === '') {
            $errors[] = 'الاسم بالعربي مطلوب';
        } elseif (mb_strlen($fullNameAr) > 300) {
            $errors[] = 'الاسم بالعربي يجب ألا يتجاوز 300 حرف';
        }
        if ($playerType === '') {
            $errors[] = 'نوع اللاعب مطلوب';
        }
        if ($playerType === 'member' && $memberId <= 0) {
            $errors[] = 'رقم العضوية مطلوب للأعضاء';
        }

        $validTypes = ['member', 'non_member'];
        if ($playerType !== '' && !in_array($playerType, $validTypes, true)) {
            $errors[] = 'نوع اللاعب غير صالح';
        }

        if ($fullNameEn !== '' && mb_strlen($fullNameEn) > 300) {
            $errors[] = 'الاسم بالإنجليزي يجب ألا يتجاوز 300 حرف';
        }
        if ($nationalId !== '' && strlen($nationalId) > 14) {
            $errors[] = 'الرقم القومي يجب ألا يتجاوز 14 رقم';
        }
        if ($phone !== '' && mb_strlen($phone) > 30) {
            $errors[] = 'رقم الهاتف يجب ألا يتجاوز 30 حرف';
        }
        if ($email !== '' && mb_strlen($email) > 200) {
            $errors[] = 'البريد الإلكتروني يجب ألا يتجاوز 200 حرف';
        }
        if ($guardianName !== '' && mb_strlen($guardianName) > 300) {
            $errors[] = 'اسم ولي الأمر يجب ألا يتجاوز 300 حرف';
        }
        if ($guardianPhone !== '' && mb_strlen($guardianPhone) > 30) {
            $errors[] = 'هاتف ولي الأمر يجب ألا يتجاوز 30 حرف';
        }
        if ($guardianNationalId !== '' && strlen($guardianNationalId) > 14) {
            $errors[] = 'الرقم القومي لولي الأمر يجب ألا يتجاوز 14 رقم';
        }
        if ($guardianRelationship !== '' && mb_strlen($guardianRelationship) > 50) {
            $errors[] = 'صلة القرابة يجب ألا تتجاوز 50 حرف';
        }

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

        $data = [
            'full_name_ar'         => $fullNameAr,
            'full_name_en'         => $fullNameEn ?: null,
            'player_type'          => $playerType,
            'member_id'            => $memberId > 0 ? $memberId : null,
            'national_id'          => $nationalId ?: null,
            'date_of_birth'        => $dateOfBirth ?: null,
            'gender'               => $gender,
            'phone'                => $phone ?: null,
            'email'                => $email ?: null,
            'guardian_name'        => $guardianName ?: null,
            'guardian_phone'       => $guardianPhone ?: null,
            'guardian_national_id' => $guardianNationalId ?: null,
            'guardian_relationship' => $guardianRelationship ?: null,
            'notes'                => $notes ?: null,
            'updated_at'           => now(),
        ];

        $db->update('sa_players', $data, 'id = ?', [(int) $id]);

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