<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Services;

use App\Core\App;
use App\Core\Logger;
use App\Modules\SportsActivity\SaConstants;

final class SaEventListenerService
{
    public static function handlePaymentCompleted(array $data): void
    {
        $entityType = $data['related_entity_type'] ?? '';

        try {
            if ($entityType === SaConstants::ENTITY_REG_FORM) {
                self::handleRegistrationFormPaid((int) ($data['related_entity_id'] ?? 0));
                return;
            }

            if ($entityType === SaConstants::ENTITY_REGISTRATIONS) {
                self::handleRegistrationPaid(
                    (int) ($data['related_entity_id'] ?? 0),
                    (int) ($data['payment_id'] ?? 0)
                );
                return;
            }

            if ($entityType === SaConstants::ENTITY_SUBSCRIPTIONS) {
                self::handleSubscriptionPaid($data);
                return;
            }

            if ($entityType === SaConstants::ENTITY_BOOKINGS) {
                self::handleBookingPaid($data);
                return;
            }

            if ($entityType === SaConstants::ENTITY_GROUP_PLAYERS) {
                self::handleEnrollmentPaid(
                    (int) ($data['related_entity_id'] ?? 0),
                    (int) ($data['payment_id'] ?? 0),
                    $data
                );
                return;
            }

            if ($entityType === SaConstants::ENTITY_PLAYER_CARDS) {
                CardRenewalService::completeRenewal(
                    (int) ($data['related_entity_id'] ?? 0),
                    (int) ($data['payment_id'] ?? 0)
                );
                return;
            }

            if ($entityType === SaConstants::ENTITY_GAME_TICKETS) {
                self::handleGameTicketPaid($data);
                return;
            }

            if ($entityType === SaConstants::ENTITY_POOL_TICKETS) {
                self::handlePoolTicketPaid($data);
                return;
            }

            if ($entityType === 'sa_pool_reservations') {
                self::handlePoolReservationPaid($data);
                return;
            }
        } catch (\Throwable $e) {
            Logger::error('SA payment_request.completed listener failed: ' . $e->getMessage());
        }
    }

    public static function handlePaymentVoided(array $data): void
    {
        try {
            $db = App::getInstance()->db();
            $paymentId = (int) ($data['payment_id'] ?? 0);
            if ($paymentId < 1) {
                return;
            }

            $sub = $db->selectOne("SELECT id FROM sa_subscriptions WHERE payment_id = ?", [$paymentId]);
            if ($sub) {
                $db->update('sa_subscriptions', [
                    'payment_status' => SaConstants::PAYMENT_UNPAID,
                    'paid_at'        => null,
                    'paid_amount'    => null,
                    'payment_id'     => null,
                    'receipt_id'     => null,
                    'receipt_number' => null,
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $sub['id']]);
            }

            $bk = $db->selectOne("SELECT id FROM sa_bookings WHERE payment_id = ?", [$paymentId]);
            if ($bk) {
                $db->update('sa_bookings', [
                    'payment_status' => SaConstants::PAYMENT_UNPAID,
                    'payment_id'     => null,
                    'receipt_id'     => null,
                    'receipt_number' => null,
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $bk['id']]);
            }

            $gameTicket = $db->selectOne("SELECT id FROM sa_game_tickets WHERE payment_id = ?", [$paymentId]);
            if ($gameTicket) {
                $db->update('sa_game_tickets', [
                    'payment_status' => SaConstants::PAYMENT_UNPAID,
                    'payment_id'     => null,
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $gameTicket['id']]);
            }

            $poolTicket = $db->selectOne("SELECT id FROM sa_pool_tickets WHERE payment_id = ?", [$paymentId]);
            if ($poolTicket) {
                $db->update('sa_pool_tickets', [
                    'payment_status' => SaConstants::PAYMENT_UNPAID,
                    'payment_id'     => null,
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $poolTicket['id']]);
            }

            $poolRes = $db->selectOne("SELECT id FROM sa_pool_reservations WHERE payment_id = ?", [$paymentId]);
            if ($poolRes) {
                $db->update('sa_pool_reservations', [
                    'payment_status' => 'pending',
                    'payment_id'     => null,
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $poolRes['id']]);
            }

            $enrollment = $db->selectOne(
                "SELECT id FROM sa_group_players WHERE activated_by_payment_id = ? AND status = 'active'",
                [$paymentId]
            );
            if ($enrollment) {
                EnrollmentService::deactivateEnrollment((int) $enrollment['id']);
            }
        } catch (\Throwable $e) {
            Logger::error('SA payment.voided listener failed: ' . $e->getMessage());
        }
    }

    private static function handleRegistrationFormPaid(int $registrationId): void
    {
        if ($registrationId < 1) {
            return;
        }
        $db = App::getInstance()->db();
        $db->update('sa_registrations', [
            'form_payment_status' => SaConstants::PAYMENT_PAID,
            'updated_at'          => date('Y-m-d H:i:s'),
        ], 'id = ?', [$registrationId]);

        $registration = $db->selectOne(
            "SELECT player_id FROM sa_registrations WHERE id = ?",
            [$registrationId]
        );
        if ($registration) {
            $db->update('sa_players', [
                'registration_fee_paid' => 1,
                'updated_at'            => date('Y-m-d H:i:s'),
            ], 'id = ?', [(int) $registration['player_id']]);
        }
    }

    private static function handleRegistrationPaid(int $registrationId, int $paymentId): void
    {
        if ($registrationId < 1) {
            return;
        }
        RegistrationWizardService::completeRegistration($registrationId, $paymentId);
    }

    private static function handleSubscriptionPaid(array $data): void
    {
        $db = App::getInstance()->db();
        $subscriptionId = (int) ($data['related_entity_id'] ?? 0);

        $db->update('sa_subscriptions', [
            'payment_status' => SaConstants::PAYMENT_PAID,
            'paid_at'        => date('Y-m-d H:i:s'),
            'paid_amount'    => $data['amount'] ?? 0,
            'payment_id'     => $data['payment_id'] ?? null,
            'receipt_id'     => $data['receipt_id'] ?? null,
            'receipt_number' => $data['receipt_number'] ?? null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [$subscriptionId]);

        $sub = $db->selectOne(
            "SELECT player_id FROM sa_subscriptions WHERE id = ?",
            [$subscriptionId]
        );
        if ($sub) {
            $reg = $db->selectOne(
                "SELECT id FROM sa_registrations WHERE player_id = ? AND status = 'assessed' AND payment_status = 'unpaid' ORDER BY id DESC LIMIT 1",
                [(int) $sub['player_id']]
            );
            if ($reg) {
                $db->update('sa_registrations', [
                    'payment_status' => SaConstants::PAYMENT_PAID,
                    'status'         => 'completed',
                    'completed_at'   => date('Y-m-d H:i:s'),
                    'updated_at'     => date('Y-m-d H:i:s'),
                ], 'id = ?', [(int) $reg['id']]);
            }
        }
    }

    private static function handleBookingPaid(array $data): void
    {
        $db = App::getInstance()->db();
        $db->update('sa_bookings', [
            'payment_status' => SaConstants::PAYMENT_PAID,
            'payment_id'     => $data['payment_id'] ?? null,
            'receipt_id'     => $data['receipt_id'] ?? null,
            'receipt_number' => $data['receipt_number'] ?? null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [(int) ($data['related_entity_id'] ?? 0)]);
    }

    private static function handleGameTicketPaid(array $data): void
    {
        $db = App::getInstance()->db();
        $ticketId = (int) ($data['related_entity_id'] ?? 0);
        if ($ticketId < 1) {
            return;
        }

        $db->update('sa_game_tickets', [
            'payment_status' => SaConstants::PAYMENT_PAID,
            'payment_id'     => $data['payment_id'] ?? null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [$ticketId]);
    }

    private static function handlePoolTicketPaid(array $data): void
    {
        $db = App::getInstance()->db();
        $ticketId = (int) ($data['related_entity_id'] ?? 0);
        if ($ticketId < 1) {
            return;
        }

        $db->update('sa_pool_tickets', [
            'payment_status' => SaConstants::PAYMENT_PAID,
            'payment_id'     => $data['payment_id'] ?? null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [$ticketId]);
    }

    private static function handlePoolReservationPaid(array $data): void
    {
        $db = App::getInstance()->db();
        $reservationId = (int) ($data['related_entity_id'] ?? 0);
        if ($reservationId < 1) {
            return;
        }

        $db->update('sa_pool_reservations', [
            'payment_status' => SaConstants::PAYMENT_PAID,
            'payment_id'     => $data['payment_id'] ?? null,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], 'id = ?', [$reservationId]);
    }

    private static function handleEnrollmentPaid(int $enrollmentId, int $paymentId, array $data): void
    {
        if ($enrollmentId < 1 || $paymentId < 1) {
            return;
        }

        $db = App::getInstance()->db();

        EnrollmentService::activateEnrollment($enrollmentId, $paymentId);

        $enrollment = $db->selectOne(
            "SELECT gp.player_id, gp.group_id, g.name_ar as group_name
             FROM sa_group_players gp
             LEFT JOIN sa_groups g ON g.id = gp.group_id
             WHERE gp.id = ?",
            [$enrollmentId]
        );

        if ($enrollment) {
            $periodStart = date('Y-m-d');
            $periodEnd = date('Y-m-t');
            $subNumber = NumberGeneratorService::subscriptionNumber();

            $db->insert('sa_subscriptions', [
                'subscription_number' => $subNumber,
                'player_id'           => (int) $enrollment['player_id'],
                'group_id'            => (int) $enrollment['group_id'],
                'period_start'        => $periodStart,
                'period_end'          => $periodEnd,
                'amount'              => $data['amount'] ?? '0.00',
                'discount_amount'     => '0.00',
                'final_amount'        => $data['amount'] ?? '0.00',
                'payment_status'      => SaConstants::PAYMENT_PAID,
                'paid_at'             => date('Y-m-d H:i:s'),
                'paid_amount'         => $data['amount'] ?? '0.00',
                'payment_id'          => $paymentId,
                'receipt_id'          => $data['receipt_id'] ?? null,
                'receipt_number'      => $data['receipt_number'] ?? null,
                'created_at'          => date('Y-m-d H:i:s'),
                'updated_at'          => date('Y-m-d H:i:s'),
            ]);
        }
    }
}
