<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Services;

use App\Core\App;
use App\Modules\Cashier\Services\PaymentRequestService;
use App\Modules\SportsActivity\SaConstants;

final class PoolTicketService
{
    public static function issueTicket(array $data): array
    {
        $db = App::getInstance()->db();
        $employee = App::getInstance()->currentEmployee();
        $branch = App::getInstance()->currentBranch();

        $facilityId = (int) ($data['facility_id'] ?? 0);
        $date = $data['booking_date'] ?? date('Y-m-d');
        $startTime = $data['start_time'] ?? '';
        $endTime = $data['end_time'] ?? '';
        $isMember = (bool) ($data['is_member'] ?? false);
        $memberId = isset($data['member_id']) ? (int) $data['member_id'] : null;
        $playerId = isset($data['player_id']) ? (int) $data['player_id'] : null;
        $guestName = $data['guest_name'] ?? null;
        $guestNationalId = $data['guest_national_id'] ?? null;

        $zone = $db->selectOne(
            "SELECT * FROM sa_pool_zone_bookings
             WHERE facility_id = ? AND booking_date = ? AND start_time <= ? AND end_time > ?
             AND access_mode = 'open_access' AND status = 'active'
             ORDER BY current_occupancy ASC LIMIT 1",
            [$facilityId, $date, $startTime . ':00', $startTime . ':00']
        );

        if (!$zone) {
            return ['success' => false, 'error' => 'لا توجد منطقة دخول حر متاحة في هذا الوقت'];
        }

        if (!empty($zone['access_restriction']) && $zone['access_restriction'] === 'members_only' && !$isMember) {
            return ['success' => false, 'error' => 'هذه المنطقة متاحة للأعضاء فقط'];
        }

        if (!empty($zone['max_occupancy']) && (int) $zone['current_occupancy'] >= (int) $zone['max_occupancy']) {
            return ['success' => false, 'error' => 'المنطقة وصلت للحد الأقصى من الإشغال'];
        }

        $price = $isMember
            ? (float) ($zone['ticket_price_member'] ?? 0)
            : (float) ($zone['ticket_price_nonmember'] ?? 0);

        $now = date('Y-m-d H:i:s');
        $employeeId = $employee ? (int) $employee->id : null;

        $db->beginTransaction();
        try {
            $ticketId = $db->insert('sa_pool_tickets', [
                'facility_id'      => $facilityId,
                'zone_booking_id'  => (int) $zone['id'],
                'booking_date'     => $date,
                'start_time'       => $zone['start_time'],
                'end_time'         => $zone['end_time'],
                'member_id'        => $memberId,
                'player_id'        => $playerId,
                'guest_name'       => $guestName,
                'guest_national_id' => $guestNationalId,
                'is_member'        => $isMember ? 1 : 0,
                'amount_paid'      => $price,
                'payment_status'   => 'unpaid',
                'status'           => SaConstants::TICKET_ISSUED,
                'issued_by'        => $employeeId,
                'branch_id'        => $branch ? (int) $branch['id'] : null,
                'created_at'       => $now,
                'updated_at'       => $now,
            ]);

            $db->query(
                "UPDATE sa_pool_zone_bookings SET current_occupancy = current_occupancy + 1, updated_at = ? WHERE id = ?",
                [$now, (int) $zone['id']]
            );

            if ($price > 0) {
                $description = 'تذكرة دخول حمام السباحة — ' . ($guestName ?: 'عضو');
                $payResult = PaymentRequestService::createRequest([
                    'member_id'           => $memberId ?? 0,
                    'payment_type'        => 'sa_pool_ticket',
                    'amount'              => (string) $price,
                    'description_ar'      => $description,
                    'related_entity_type' => 'sa_pool_tickets',
                    'related_entity_id'   => $ticketId,
                ]);

                if ($payResult['success']) {
                    $db->update('sa_pool_tickets', [
                        'payment_request_id' => (int) $payResult['request_id'],
                        'updated_at'         => $now,
                    ], 'id = ?', [$ticketId]);
                }
            }

            $db->commit();
        } catch (\Throwable $e) {
            $db->rollBack();
            return ['success' => false, 'error' => 'فشل إصدار التذكرة: ' . $e->getMessage()];
        }

        return [
            'success'   => true,
            'ticket_id' => $ticketId,
            'price'     => $price,
            'zone_id'   => (int) $zone['id'],
        ];
    }

    public static function cancelTicket(int $ticketId, string $reason = ''): array
    {
        $db = App::getInstance()->db();

        $ticket = $db->selectOne("SELECT * FROM sa_pool_tickets WHERE id = ?", [$ticketId]);
        if (!$ticket) {
            return ['success' => false, 'error' => 'التذكرة غير موجودة'];
        }

        if ($ticket['status'] === 'cancelled') {
            return ['success' => false, 'error' => 'التذكرة ملغاة بالفعل'];
        }

        $now = date('Y-m-d H:i:s');

        $db->update('sa_pool_tickets', [
            'status'     => SaConstants::TICKET_CANCELLED,
            'updated_at' => $now,
        ], 'id = ?', [$ticketId]);

        if (!empty($ticket['zone_booking_id'])) {
            $db->query(
                "UPDATE sa_pool_zone_bookings SET current_occupancy = GREATEST(0, current_occupancy - 1), updated_at = ? WHERE id = ?",
                [$now, (int) $ticket['zone_booking_id']]
            );
        }

        return ['success' => true];
    }

    public static function recordEntry(int $ticketId): array
    {
        $db = App::getInstance()->db();
        $now = date('Y-m-d H:i:s');

        $db->update('sa_pool_tickets', [
            'status'     => SaConstants::TICKET_ACTIVE,
            'entry_time' => $now,
            'updated_at' => $now,
        ], 'id = ?', [$ticketId]);

        return ['success' => true];
    }

    public static function recordExit(int $ticketId): array
    {
        $db = App::getInstance()->db();
        $now = date('Y-m-d H:i:s');

        $ticket = $db->selectOne("SELECT * FROM sa_pool_tickets WHERE id = ?", [$ticketId]);
        if (!$ticket) {
            return ['success' => false, 'error' => 'التذكرة غير موجودة'];
        }

        $db->update('sa_pool_tickets', [
            'status'     => SaConstants::TICKET_COMPLETED,
            'exit_time'  => $now,
            'updated_at' => $now,
        ], 'id = ?', [$ticketId]);

        if (!empty($ticket['zone_booking_id'])) {
            $db->query(
                "UPDATE sa_pool_zone_bookings SET current_occupancy = GREATEST(0, current_occupancy - 1), updated_at = ? WHERE id = ?",
                [$now, (int) $ticket['zone_booking_id']]
            );
        }

        return ['success' => true];
    }

    public static function getActiveTickets(int $facilityId, string $date): array
    {
        $db = App::getInstance()->db();
        return $db->select(
            "SELECT * FROM sa_pool_tickets
             WHERE facility_id = ? AND booking_date = ? AND status IN ('issued','active')
             ORDER BY created_at DESC",
            [$facilityId, $date]
        );
    }
}
