<?php
declare(strict_types=1);

/**
 * Sports Activities Event Listeners
 *
 * Cross-module integration wiring for the sports system.
 * Included from PlayerAffairs/bootstrap.php.
 */

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

// ─────────────────────────────────────────────────────────────
// payment.completed → auto-set registration_fee_paid,
//                     auto-confirm reservations,
//                     auto-update rental deposits,
//                     auto-pay activity subscriptions
// ─────────────────────────────────────────────────────────────
EventBus::listen('payment.completed', function (array $data) {
    try {
        $db = App::getInstance()->db();
        $paymentType = $data['payment_type'] ?? '';
        $paymentId = (int) ($data['payment_id'] ?? 0);
        $playerId = (int) ($data['player_id'] ?? 0);
        $ts = date('Y-m-d H:i:s');

        // Sports registration fee payment → mark player as fee paid
        if (in_array($paymentType, ['sports_reg_member', 'sports_reg_nonmember']) && $playerId > 0) {
            $db->update('players', [
                'registration_fee_paid' => 1,
                'updated_at'            => $ts,
            ], 'id = ?', [$playerId]);

            Logger::info("Player #{$playerId} registration fee marked as paid");
        }

        // Facility reservation payment → auto-confirm reservation
        if ($paymentType === 'facility_reservation' && $paymentId > 0) {
            $reservation = $db->selectOne(
                "SELECT id FROM reservations WHERE payment_id = ? AND status = 'pending'",
                [$paymentId]
            );
            if ($reservation) {
                $db->update('reservations', [
                    'status'       => 'confirmed',
                    'confirmed_at' => $ts,
                    'updated_at'   => $ts,
                ], 'id = ?', [(int) $reservation['id']]);

                EventBus::dispatch('reservation.confirmed', [
                    'reservation_id' => (int) $reservation['id'],
                    'payment_id'     => $paymentId,
                ]);
                Logger::info("Reservation #{$reservation['id']} auto-confirmed after payment");
            }
        }

        // Rental deposit payment → update deposit status
        if ($paymentType === 'rental_deposit' && $paymentId > 0) {
            $contract = $db->selectOne(
                "SELECT id FROM rental_contracts WHERE deposit_payment_id = ? AND deposit_status = 'pending'",
                [$paymentId]
            );
            if ($contract) {
                $db->update('rental_contracts', [
                    'deposit_status'     => 'collected',
                    'deposit_payment_id' => $paymentId,
                    'updated_at'         => $ts,
                ], 'id = ?', [(int) $contract['id']]);

                EventBus::dispatch('rental.deposit_collected', [
                    'contract_id' => (int) $contract['id'],
                    'payment_id'  => $paymentId,
                ]);
                Logger::info("Rental deposit collected for contract #{$contract['id']}");
            }
        }

        // Activity subscription payment → mark sub as paid + activate card
        if ($paymentType === 'activity_subscription' && $paymentId > 0) {
            $sub = $db->selectOne(
                "SELECT id, player_id FROM activity_subscriptions WHERE payment_id = ? AND status IN ('pending', 'overdue')",
                [$paymentId]
            );
            if ($sub) {
                $db->update('activity_subscriptions', [
                    'status'     => 'paid',
                    'paid_at'    => $ts,
                    'updated_at' => $ts,
                ], 'id = ?', [(int) $sub['id']]);

                // Activate the player's card
                $db->update('players', [
                    'card_status' => 'active',
                    'updated_at'  => $ts,
                ], 'id = ? AND card_status != ?', [(int) $sub['player_id'], 'active']);

                EventBus::dispatch('activity_sub.paid', [
                    'subscription_id' => (int) $sub['id'],
                    'player_id'       => (int) $sub['player_id'],
                    'payment_id'      => $paymentId,
                ]);
                EventBus::dispatch('player.card_activated', [
                    'player_id' => (int) $sub['player_id'],
                    'reason'    => 'سداد اشتراك النشاط الرياضي',
                ]);
                Logger::info("Activity sub #{$sub['id']} paid, player #{$sub['player_id']} card activated");
            }
        }

    } catch (\Throwable $e) {
        Logger::error("Sports payment.completed handler error: " . $e->getMessage(), $data);
    }
}, 50); // Priority 50 (lower than the main payment handler at 100)


// ─────────────────────────────────────────────────────────────
// academy.enrollment_created → auto-generate first month subscription
// ─────────────────────────────────────────────────────────────
EventBus::listen('academy.enrollment_created', function (array $data) {
    try {
        $db = App::getInstance()->db();
        $enrollmentId = (int) ($data['enrollment_id'] ?? 0);
        $playerId = (int) ($data['player_id'] ?? 0);
        $academyId = (int) ($data['academy_id'] ?? 0);
        $ts = date('Y-m-d H:i:s');

        if ($enrollmentId <= 0 || $playerId <= 0 || $academyId <= 0) return;

        $enrollment = $db->selectOne("SELECT * FROM academy_enrollments WHERE id = ?", [$enrollmentId]);
        if (!$enrollment) return;

        $player = $db->selectOne("SELECT player_type FROM players WHERE id = ?", [$playerId]);
        if (!$player) return;

        $academy = $db->selectOne("SELECT discipline_id FROM academies WHERE id = ?", [$academyId]);
        if (!$academy) return;

        $month = date('Y-m');
        $enrollmentDay = (int) ($enrollment['enrollment_day'] ?? (int) date('j'));

        // Check if subscription already exists
        $existing = $db->selectOne(
            "SELECT id FROM activity_subscriptions WHERE player_id = ? AND enrollment_id = ? AND subscription_month = ?",
            [$playerId, $enrollmentId, $month]
        );
        if ($existing) return;

        // Look up pricing
        $isMember = ($player['player_type'] === 'member');
        $rateCol = $isMember ? 'member_rate' : 'nonmember_rate';

        $pricing = $db->selectOne(
            "SELECT {$rateCol} AS rate FROM activity_pricing WHERE pricing_type = 'academy' AND reference_id = ? AND is_active = 1 AND effective_from <= CURDATE() AND (effective_to IS NULL OR effective_to >= CURDATE())",
            [$academyId]
        );
        if (!$pricing) {
            $pricing = $db->selectOne(
                "SELECT {$rateCol} AS rate FROM activity_pricing WHERE pricing_type = 'discipline' AND reference_id = ? AND is_active = 1 AND effective_from <= CURDATE() AND (effective_to IS NULL OR effective_to >= CURDATE())",
                [(int) $academy['discipline_id']]
            );
        }

        $baseRate = $pricing ? (string) $pricing['rate'] : '0.00';

        // Half-month: only for FIRST subscription month AND enrollment after 15th
        $isFirstMonth = !$db->selectOne(
            "SELECT id FROM activity_subscriptions WHERE enrollment_id = ? AND subscription_month < ? LIMIT 1",
            [$enrollmentId, $month]
        );
        $isHalfMonth = ($isFirstMonth && $enrollmentDay > 15) ? 1 : 0;
        $appliedRate = $isHalfMonth ? bcdiv($baseRate, '2', 2) : $baseRate;

        // Due date: for first month with enrollment after 7th, give 7 days grace
        $defaultDue = date('Y-m-07');
        if ($isFirstMonth && $enrollmentDay > 7) {
            $dueDate = date('Y-m-d', strtotime('+7 days'));
        } else {
            $dueDate = $defaultDue;
        }

        $subId = $db->insert('activity_subscriptions', [
            'player_id'          => $playerId,
            'enrollment_id'      => $enrollmentId,
            'discipline_id'      => (int) $academy['discipline_id'],
            'subscription_month' => $month,
            'player_type'        => $player['player_type'],
            'base_rate'          => $baseRate,
            'is_half_month'      => $isHalfMonth,
            'applied_rate'       => $appliedRate,
            'discount'           => '0.00',
            'total_amount'       => $appliedRate,
            'status'             => 'pending',
            'due_date'           => $dueDate,
            'created_at'         => $ts,
            'updated_at'         => $ts,
        ]);

        EventBus::dispatch('activity_sub.generated', [
            'subscription_id' => $subId,
            'player_id'       => $playerId,
            'enrollment_id'   => $enrollmentId,
            'month'           => $month,
            'amount'          => $appliedRate,
            'is_half_month'   => $isHalfMonth,
        ]);

        Logger::info("Auto-generated activity sub #{$subId} for enrollment #{$enrollmentId} (half_month={$isHalfMonth})");

    } catch (\Throwable $e) {
        Logger::error("academy.enrollment_created handler error: " . $e->getMessage(), $data);
    }
});


// ─────────────────────────────────────────────────────────────
// academy.enrollment_dropped → cancel pending unpaid subscriptions
// ─────────────────────────────────────────────────────────────
EventBus::listen('academy.enrollment_dropped', function (array $data) {
    try {
        $db = App::getInstance()->db();
        $enrollmentId = (int) ($data['enrollment_id'] ?? 0);
        $ts = date('Y-m-d H:i:s');

        if ($enrollmentId <= 0) return;

        // Cancel all pending (unpaid) subscriptions for this enrollment
        $pending = $db->select(
            "SELECT id, player_id, subscription_month FROM activity_subscriptions WHERE enrollment_id = ? AND status IN ('pending', 'overdue')",
            [$enrollmentId]
        );

        foreach ($pending as $sub) {
            $db->update('activity_subscriptions', [
                'status'     => 'revoked',
                'revoked_at' => $ts,
                'notes'      => 'تم الإلغاء بسبب الانسحاب من الأكاديمية',
                'updated_at' => $ts,
            ], 'id = ?', [(int) $sub['id']]);

            Logger::info("Activity sub #{$sub['id']} cancelled due to enrollment #{$enrollmentId} drop");
        }

    } catch (\Throwable $e) {
        Logger::error("academy.enrollment_dropped handler error: " . $e->getMessage(), $data);
    }
});


// ─────────────────────────────────────────────────────────────
// activity_sub.paid → activate player card (backup if not already activated)
// ─────────────────────────────────────────────────────────────
EventBus::listen('activity_sub.paid', function (array $data) {
    try {
        $db = App::getInstance()->db();
        $playerId = (int) ($data['player_id'] ?? 0);
        $ts = date('Y-m-d H:i:s');

        if ($playerId <= 0) return;

        $player = $db->selectOne("SELECT card_status FROM players WHERE id = ?", [$playerId]);
        if ($player && $player['card_status'] !== 'active') {
            $db->update('players', [
                'card_status' => 'active',
                'updated_at'  => $ts,
            ], 'id = ?', [$playerId]);

            EventBus::dispatch('player.card_activated', [
                'player_id' => $playerId,
                'reason'    => 'سداد اشتراك النشاط',
            ]);
        }
    } catch (\Throwable $e) {
        Logger::error("activity_sub.paid card activation error: " . $e->getMessage());
    }
});


// ─────────────────────────────────────────────────────────────
// player.registered → dispatch for SMS notification
// ─────────────────────────────────────────────────────────────
EventBus::listen('player.registered', function (array $data) {
    try {
        $playerId = (int) ($data['player_id'] ?? 0);
        $playerName = $data['player_name'] ?? '';
        $serial = $data['registration_serial'] ?? '';
        $phone = $data['phone'] ?? '';

        if ($phone && $playerName && $serial) {
            EventBus::dispatchAsync('sms.send', [
                'template_code' => 'SMS_SPORTS_REGISTRATION',
                'phone'         => $phone,
                'variables'     => [
                    'player_name'         => $playerName,
                    'registration_serial' => $serial,
                ],
            ]);
        }
    } catch (\Throwable $e) {
        Logger::error("player.registered SMS handler error: " . $e->getMessage());
    }
});
