<?php
declare(strict_types=1);

namespace App\Modules\PlayerApi\Services;

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

final class PlayerFreeTimeService
{
    private \App\Core\Database $db;

    public function __construct()
    {
        $this->db = App::getInstance()->db();
    }

    public function getFreeTimeFacilities(): array
    {
        return $this->db->select(
            "SELECT DISTINCT f.id, f.name_ar, f.facility_type, f.location,
                    f.hourly_rate_member, f.hourly_rate_nonmember
             FROM facilities f
             INNER JOIN facility_time_slots fts ON fts.facility_id = f.id
             WHERE f.is_active = 1 AND f.is_archived = 0
             AND fts.access_type IN ('open', 'members_only')
             AND f.facility_type IN ('pool', 'hall', 'court', 'table', 'device')
             ORDER BY f.name_ar"
        );
    }

    public function getFreeTimeSlots(int $facilityId, string $date): array
    {
        $dayOfWeek = (int) date('w', strtotime($date));

        return $this->db->select(
            "SELECT fts.id, fts.start_time, fts.end_time, fts.access_type,
                    fts.member_price, fts.guest_price
             FROM facility_time_slots fts
             WHERE fts.facility_id = ? AND fts.day_of_week = ? AND fts.is_active = 1
             AND fts.access_type IN ('open', 'members_only')
             ORDER BY fts.start_time",
            [$facilityId, $dayOfWeek]
        );
    }

    public function recordEntry(int $playerId, array $data): array
    {
        $player = App::getInstance()->currentPlayer();
        $isMember = !empty($player->member_id);

        $facility = $this->db->selectOne(
            "SELECT id, name_ar, hourly_rate_member, hourly_rate_nonmember
             FROM facilities WHERE id = ? AND is_active = 1",
            [$data['facility_id']]
        );

        if (!$facility) {
            return ['error' => 'المرفق غير متاح'];
        }

        $dayOfWeek = (int) date('w', strtotime($data['date'] ?? date('Y-m-d')));
        $currentTime = $data['entry_time'] ?? date('H:i:s');

        $slot = $this->db->selectOne(
            "SELECT access_type, member_price, guest_price
             FROM facility_time_slots
             WHERE facility_id = ? AND day_of_week = ? AND start_time <= ? AND end_time > ? AND is_active = 1
             AND access_type IN ('open', 'members_only')",
            [$data['facility_id'], $dayOfWeek, $currentTime, $currentTime]
        );

        if (!$slot) {
            return ['error' => 'لا يوجد وقت حر متاح الآن'];
        }

        if ($slot['access_type'] === 'members_only' && !$isMember) {
            return ['error' => 'هذا الوقت مخصص للأعضاء فقط'];
        }

        $amount = $isMember
            ? (float) ($slot['member_price'] ?? $facility['hourly_rate_member'] ?? 0)
            : (float) ($slot['guest_price'] ?? $facility['hourly_rate_nonmember'] ?? 0);

        $this->db->insert('free_time_entries', [
            'player_id' => $playerId,
            'member_id' => $player->member_id ?? null,
            'facility_id' => $data['facility_id'],
            'entry_date' => $data['date'] ?? date('Y-m-d'),
            'entry_time' => $currentTime,
            'activity_type' => $data['activity_type'] ?? 'recreation',
            'is_member' => $isMember ? 1 : 0,
            'amount_paid' => $amount,
            'status' => 'active',
        ]);

        $entryId = (int) $this->db->selectOne("SELECT LAST_INSERT_ID() as id")['id'];

        EventBus::dispatch('player.free_time_entry', [
            'player_id' => $playerId,
            'entry_id' => $entryId,
            'facility_name' => $facility['name_ar'],
        ]);

        return [
            'id' => $entryId,
            'amount_paid' => $amount,
            'facility_name' => $facility['name_ar'],
        ];
    }
}
