<?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\SportsActivity\Services\EnrollmentService;
use App\Modules\SportsActivity\SaConstants;

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

        $discipline = $db->selectOne(
            "SELECT id FROM sa_disciplines WHERE code = 'SWIMMING' AND is_archived = 0"
        );
        if (!$discipline) {
            return $this->redirect('/sa')->withError('لم يتم العثور على نشاط السباحة');
        }
        $disciplineId = (int) $discipline['id'];

        $players = $db->select("
            SELECT pl.id, pl.full_name_ar, pl.date_of_birth, pl.gender, pl.phone,
                   pl.medical_status, pl.photo_path, pl.player_type, pl.created_at,
                   (SELECT MAX(doc.created_at) FROM sa_player_documents doc
                    WHERE doc.player_id = pl.id AND doc.document_type = 'medical_cert') as medical_upload_date
            FROM sa_players pl
            WHERE pl.is_archived = 0
            AND EXISTS (
                SELECT 1 FROM sa_player_documents doc
                WHERE doc.player_id = pl.id AND doc.document_type = 'medical_cert'
            )
            AND NOT EXISTS (
                SELECT 1 FROM sa_group_players gp
                INNER JOIN sa_groups g ON g.id = gp.group_id
                INNER JOIN sa_programs p ON p.id = g.program_id
                WHERE p.discipline_id = ? AND gp.player_id = pl.id AND gp.status IN ('active', 'pending_payment')
            )
            ORDER BY pl.created_at DESC
        ", [$disciplineId]);

        return $this->view('SportsActivity.Views.swimming.assign', [
            'players'      => $players,
            'player'       => null,
            'groups'       => [],
            'mode'         => 'list',
            'disciplineId' => $disciplineId,
        ]);
    }

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

        $discipline = $db->selectOne(
            "SELECT id FROM sa_disciplines WHERE code = 'SWIMMING' AND is_archived = 0"
        );
        if (!$discipline) {
            return $this->redirect('/sa')->withError('لم يتم العثور على نشاط السباحة');
        }
        $disciplineId = (int) $discipline['id'];

        $isRegistrationId = (bool) $db->selectOne(
            "SELECT 1 FROM sa_registrations WHERE id = ?", [(int) $id]
        );

        if ($isRegistrationId) {
            $registration = $db->selectOne(
                "SELECT r.*, p.id as player_id, p.full_name_ar, p.date_of_birth, p.gender,
                        p.phone, p.photo_path, p.player_type as player_type, p.medical_status
                 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/assign')->withError('التسجيل غير موجود');
            }
            $player = $registration;
            $playerId = (int) $registration['player_id'];
        } else {
            $player = $db->selectOne(
                "SELECT *, id as player_id FROM sa_players WHERE id = ? AND is_archived = 0",
                [(int) $id]
            );
            if (!$player) {
                return $this->redirect('/sa/swimming/assign')->withError('اللاعب غير موجود');
            }
            $playerId = (int) $id;
        }

        $hasMedical = (bool) $db->selectOne(
            "SELECT 1 FROM sa_player_documents WHERE player_id = ? AND document_type = 'medical_cert'",
            [$playerId]
        );
        if (!$hasMedical) {
            return $this->redirect('/sa/swimming/register')->withError('يجب رفع الشهادة الطبية أولاً');
        }

        $selectedDiscipline = (int) ($request->get('discipline_id', 0) ?: $disciplineId);

        $groups = $db->select("
            SELECT g.id, g.name_ar, g.current_count, g.min_age, g.max_age,
                   p.name_ar as program_name, p.max_capacity, p.monthly_fee_member, p.monthly_fee_nonmember,
                   p.age_from, p.age_to, p.id as program_id,
                   c.full_name_ar as coach_name,
                   d.name_ar as discipline_name
            FROM sa_groups g
            INNER JOIN sa_programs p ON p.id = g.program_id
            INNER JOIN sa_disciplines d ON d.id = p.discipline_id
            LEFT JOIN sa_coaches c ON c.id = g.coach_id
            WHERE p.discipline_id = ? AND g.status = 'active' AND g.is_archived = 0
            ORDER BY p.name_ar ASC, g.name_ar ASC
        ", [$selectedDiscipline]);

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

        $playerAge = null;
        if (!empty($player['date_of_birth'])) {
            $playerAge = (int) date_diff(
                date_create($player['date_of_birth']),
                date_create()
            )->y;
        }

        return $this->view('SportsActivity.Views.swimming.assign', [
            'players'             => [],
            'player'              => $player,
            'playerId'            => $playerId,
            'playerAge'           => $playerAge,
            'groups'              => $groups,
            'mode'                => 'assign',
            'disciplineId'        => $disciplineId,
            'selectedDiscipline'  => $selectedDiscipline,
            'disciplines'         => $disciplines,
        ]);
    }

    public function assign(Request $request, string $id): Response
    {
        $db = App::getInstance()->db();
        $groupId = (int) $request->post('group_id', 0);

        if ($groupId <= 0) {
            return $this->json(['success' => false, 'error' => 'اختر مجموعة']);
        }

        $isRegistrationId = (bool) $db->selectOne(
            "SELECT 1 FROM sa_registrations WHERE id = ?", [(int) $id]
        );

        if ($isRegistrationId) {
            $registration = $db->selectOne(
                "SELECT player_id FROM sa_registrations WHERE id = ?", [(int) $id]
            );
            $playerId = (int) $registration['player_id'];
        } else {
            $playerId = (int) $id;
        }

        $result = EnrollmentService::enroll($groupId, $playerId);

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

        if ($isRegistrationId) {
            $db->update('sa_registrations', [
                'group_id'   => $groupId,
                'status'     => SaConstants::REG_PENDING_PAYMENT,
                'updated_at' => date('Y-m-d H:i:s'),
            ], 'id = ?', [(int) $id]);
        }

        return $this->json([
            'success'        => true,
            'enrollment_id'  => $result['enrollment_id'],
            'request_id'     => $result['request_id'],
            'request_number' => $result['request_number'],
            'fee'            => $result['fee'],
            'redirect'       => '/sa/swimming/assign/' . $id . '?done=1',
        ]);
    }
}
