<?php
declare(strict_types=1);

namespace App\Modules\PlaygroundAdmin\Services;

use App\Core\App;

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

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

    public function getMirrorState(int $playgroundId, string $date): array
    {
        $playground = $this->db->selectOne("SELECT * FROM playground_configurations WHERE id = ?", [$playgroundId]);
        if (!$playground) {
            return [];
        }

        $facilityId = (int) $playground['facility_id'];
        $hours = $this->getOperatingHours($playground);

        $reservations = $this->db->select(
            "SELECT r.id, r.start_time, r.end_time, r.booker_type, r.booker_id, r.status, r.total_amount,
                    CASE WHEN r.booker_type = 'player' THEN p.name_ar
                         WHEN r.booker_type = 'member' THEN m.name_ar
                         ELSE 'ضيف' END as booker_name
             FROM reservations r
             LEFT JOIN players p ON r.booker_type = 'player' AND p.id = r.booker_id
             LEFT JOIN members m ON r.booker_type = 'member' AND m.id = r.booker_id
             WHERE r.facility_id = ? AND r.reservation_date = ? AND r.status NOT IN ('cancelled', 'no_show')
             ORDER BY r.start_time",
            [$facilityId, $date]
        );

        $privateMatches = $this->db->select(
            "SELECT id, start_time, end_time, team_a_name, team_b_name, match_type, total_cost, status
             FROM private_match_bookings
             WHERE facility_id = ? AND match_date = ? AND status NOT IN ('cancelled')
             ORDER BY start_time",
            [$facilityId, $date]
        );

        $scheduledSlots = [];
        $activeSched = $this->db->selectOne(
            "SELECT id FROM playground_monthly_schedules WHERE playground_id = ? AND status = 'active' LIMIT 1",
            [$playgroundId]
        );
        if ($activeSched) {
            $scheduledSlots = $this->db->select(
                "SELECT pss.*, c.name_ar as coach_name, a.name_ar as academy_name
                 FROM playground_schedule_slots pss
                 LEFT JOIN coaches c ON c.id = pss.coach_id
                 LEFT JOIN academies a ON a.id = pss.academy_id
                 WHERE pss.schedule_id = ? AND pss.slot_date = ?
                 ORDER BY pss.slot_hour, pss.row_number",
                [(int) $activeSched['id'], $date]
            );
        }

        $mirrorGrid = [];
        foreach ($hours as $hour) {
            $hourStr = $hour . ':00';
            $nextHour = date('H:i:s', strtotime($hourStr) + 3600);

            $hourData = [
                'hour' => $hour,
                'reservations' => [],
                'private_matches' => [],
                'training_slots' => [],
                'status' => 'free',
            ];

            foreach ($reservations as $res) {
                if ($res['start_time'] < $nextHour && $res['end_time'] > $hourStr) {
                    $hourData['reservations'][] = $res;
                    $hourData['status'] = 'booked';
                }
            }

            foreach ($privateMatches as $pm) {
                if ($pm['start_time'] < $nextHour && $pm['end_time'] > $hourStr) {
                    $hourData['private_matches'][] = $pm;
                    $hourData['status'] = 'booked';
                }
            }

            foreach ($scheduledSlots as $slot) {
                if ($slot['slot_hour'] === $hourStr) {
                    $hourData['training_slots'][] = $slot;
                    $hourData['status'] = 'training';
                }
            }

            $mirrorGrid[] = $hourData;
        }

        return [
            'playground' => $playground,
            'date' => $date,
            'hours' => $mirrorGrid,
            'has_rows' => (bool) $playground['has_rows'],
            'row_count' => (int) ($playground['row_count'] ?? 0),
        ];
    }

    private function getOperatingHours(array $playground): array
    {
        $opHours = json_decode($playground['operating_hours_json'] ?? '{}', true);
        $startHour = (int) ($opHours['start'] ?? 7);
        $endHour = (int) ($opHours['end'] ?? 22);

        $hours = [];
        for ($h = $startHour; $h < $endHour; $h++) {
            $hours[] = str_pad((string) $h, 2, '0', STR_PAD_LEFT) . ':00';
        }
        return $hours;
    }
}
