<?php
declare(strict_types=1);

namespace App\Modules\Academies\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Core\Logger;

class EnrollmentService
{
    /**
     * Enroll a player in an academy level.
     */
    public static function enroll(int $playerId, int $academyId, int $levelId, ?int $scheduleId = null, ?string $season = null): int
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();
        $ts = date('Y-m-d H:i:s');

        // Check for duplicate active enrollment
        $existing = $db->selectOne(
            "SELECT id FROM academy_enrollments WHERE player_id = ? AND academy_id = ? AND status = 'active'",
            [$playerId, $academyId]
        );
        if ($existing) {
            throw new \RuntimeException('اللاعب مسجل بالفعل في هذه الأكاديمية');
        }

        $enrollmentId = $db->insert('academy_enrollments', [
            'player_id'      => $playerId,
            'academy_id'     => $academyId,
            'level_id'       => $levelId,
            'schedule_id'    => $scheduleId,
            'season'         => $season,
            'enrolled_at'    => $ts,
            'enrollment_day' => (int) date('j'),
            'status'         => 'active',
            'created_by'     => $employee ? (int) $employee->id : null,
            'created_at'     => $ts,
            'updated_at'     => $ts,
        ]);

        EventBus::dispatch('academy.enrollment_created', [
            'enrollment_id' => $enrollmentId,
            'player_id'     => $playerId,
            'academy_id'    => $academyId,
            'level_id'      => $levelId,
        ]);

        Logger::info("Player #{$playerId} enrolled in academy #{$academyId} level #{$levelId}");
        return $enrollmentId;
    }

    /**
     * Promote an enrollment to a new level.
     * Creates a new enrollment record linked to the previous one via promoted_from_id.
     */
    public static function promote(int $enrollmentId, int $newLevelId): int
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();
        $ts = date('Y-m-d H:i:s');

        $enrollment = $db->selectOne("SELECT * FROM academy_enrollments WHERE id = ?", [$enrollmentId]);
        if (!$enrollment) {
            throw new \RuntimeException('التسجيل غير موجود');
        }
        if ($enrollment['status'] !== 'active') {
            throw new \RuntimeException('لا يمكن ترقية تسجيل غير نشط');
        }

        // Mark current enrollment as promoted
        $db->update('academy_enrollments', [
            'status'     => 'promoted',
            'updated_at' => $ts,
        ], 'id = ?', [$enrollmentId]);

        // Create new enrollment at the higher level
        $newEnrollmentId = $db->insert('academy_enrollments', [
            'player_id'       => (int) $enrollment['player_id'],
            'academy_id'      => (int) $enrollment['academy_id'],
            'level_id'        => $newLevelId,
            'schedule_id'     => $enrollment['schedule_id'] ? (int) $enrollment['schedule_id'] : null,
            'season'          => $enrollment['season'],
            'enrolled_at'     => $ts,
            'enrollment_day'  => (int) date('j'),
            'status'          => 'active',
            'promoted_from_id'=> $enrollmentId,
            'created_by'      => $employee ? (int) $employee->id : null,
            'created_at'      => $ts,
            'updated_at'      => $ts,
        ]);

        EventBus::dispatch('academy.enrollment_promoted', [
            'old_enrollment_id' => $enrollmentId,
            'new_enrollment_id' => $newEnrollmentId,
            'player_id'         => (int) $enrollment['player_id'],
            'academy_id'        => (int) $enrollment['academy_id'],
            'new_level_id'      => $newLevelId,
        ]);

        Logger::info("Enrollment #{$enrollmentId} promoted to level #{$newLevelId} → new enrollment #{$newEnrollmentId}");
        return $newEnrollmentId;
    }

    /**
     * Suspend an enrollment.
     */
    public static function suspend(int $enrollmentId, ?string $reason = null): void
    {
        $db = App::getInstance()->db();
        $ts = date('Y-m-d H:i:s');

        $enrollment = $db->selectOne("SELECT * FROM academy_enrollments WHERE id = ?", [$enrollmentId]);
        if (!$enrollment) {
            throw new \RuntimeException('التسجيل غير موجود');
        }
        if ($enrollment['status'] !== 'active') {
            throw new \RuntimeException('لا يمكن إيقاف تسجيل غير نشط');
        }

        $db->update('academy_enrollments', [
            'status'     => 'suspended',
            'updated_at' => $ts,
        ], 'id = ?', [$enrollmentId]);

        EventBus::dispatch('academy.enrollment_suspended', [
            'enrollment_id' => $enrollmentId,
            'player_id'     => (int) $enrollment['player_id'],
            'academy_id'    => (int) $enrollment['academy_id'],
            'reason'        => $reason,
        ]);

        Logger::info("Enrollment #{$enrollmentId} suspended" . ($reason ? ": {$reason}" : ''));
    }

    /**
     * Drop (withdraw) an enrollment.
     */
    public static function drop(int $enrollmentId, ?string $reason = null): void
    {
        $db = App::getInstance()->db();
        $ts = date('Y-m-d H:i:s');

        $enrollment = $db->selectOne("SELECT * FROM academy_enrollments WHERE id = ?", [$enrollmentId]);
        if (!$enrollment) {
            throw new \RuntimeException('التسجيل غير موجود');
        }
        if (!in_array($enrollment['status'], ['active', 'suspended'])) {
            throw new \RuntimeException('لا يمكن إلغاء هذا التسجيل');
        }

        $db->update('academy_enrollments', [
            'status'         => 'dropped',
            'dropped_at'     => $ts,
            'dropped_reason' => $reason,
            'updated_at'     => $ts,
        ], 'id = ?', [$enrollmentId]);

        EventBus::dispatch('academy.enrollment_dropped', [
            'enrollment_id' => $enrollmentId,
            'player_id'     => (int) $enrollment['player_id'],
            'academy_id'    => (int) $enrollment['academy_id'],
            'reason'        => $reason,
        ]);

        Logger::info("Enrollment #{$enrollmentId} dropped" . ($reason ? ": {$reason}" : ''));
    }

    /**
     * Reactivate a suspended enrollment.
     */
    public static function reactivate(int $enrollmentId): void
    {
        $db = App::getInstance()->db();
        $ts = date('Y-m-d H:i:s');

        $enrollment = $db->selectOne("SELECT * FROM academy_enrollments WHERE id = ?", [$enrollmentId]);
        if (!$enrollment) {
            throw new \RuntimeException('التسجيل غير موجود');
        }
        if ($enrollment['status'] !== 'suspended') {
            throw new \RuntimeException('لا يمكن إعادة تفعيل إلا التسجيلات الموقفة');
        }

        $db->update('academy_enrollments', [
            'status'     => 'active',
            'updated_at' => $ts,
        ], 'id = ?', [$enrollmentId]);

        EventBus::dispatch('academy.enrollment_reactivated', [
            'enrollment_id' => $enrollmentId,
            'player_id'     => (int) $enrollment['player_id'],
            'academy_id'    => (int) $enrollment['academy_id'],
        ]);

        Logger::info("Enrollment #{$enrollmentId} reactivated");
    }
}
