<?php
declare(strict_types=1);

namespace App\Modules\Reservations\Services;

use App\Core\App;
use App\Core\EventBus;
use App\Modules\Scheduling\Services\ConflictDetectionService;

class PrivateMatchService
{
    public static function createBooking(array $data): int
    {
        $db = App::getInstance()->db();

        $facilityId = (int) $data['facility_id'];
        $bookingDate = $data['booking_date'];
        $startTime = $data['start_time'];
        $endTime = $data['end_time'];

        $conflicts = ConflictDetectionService::checkFacilityOverlap([
            'facility_id' => $facilityId,
            'date'        => $bookingDate,
            'start_time'  => $startTime,
            'end_time'    => $endTime,
        ]);

        if (!empty($conflicts)) {
            throw new \RuntimeException('يوجد تعارض في الحجز: ' . ($conflicts[0]['description'] ?? ''), 409);
        }

        $facilityCost = (float) ($data['facility_cost'] ?? 0);
        $refereeCost = !empty($data['has_referee']) ? (float) ($data['referee_cost'] ?? 50) : 0;
        $totalCost = $facilityCost + $refereeCost;

        $db->insert('private_match_bookings', [
            'facility_id'        => $facilityId,
            'booked_by_member_id'=> !empty($data['member_id']) ? (int) $data['member_id'] : null,
            'booked_by_name'     => $data['booked_by_name'] ?? null,
            'booked_by_phone'    => $data['booked_by_phone'] ?? null,
            'booking_date'       => $bookingDate,
            'start_time'         => $startTime,
            'end_time'           => $endTime,
            'match_type'         => $data['match_type'] ?? 'friendly',
            'team_a_name'        => $data['team_a_name'] ?? null,
            'team_b_name'        => $data['team_b_name'] ?? null,
            'players_count'      => (int) ($data['players_count'] ?? 10),
            'has_referee'        => !empty($data['has_referee']) ? 1 : 0,
            'referee_cost'       => $refereeCost,
            'facility_cost'      => $facilityCost,
            'total_cost'         => $totalCost,
            'deposit_paid'       => (float) ($data['deposit_paid'] ?? 0),
            'status'             => 'pending',
            'payment_status'     => ((float) ($data['deposit_paid'] ?? 0)) >= $totalCost ? 'paid' : (((float) ($data['deposit_paid'] ?? 0)) > 0 ? 'partial' : 'unpaid'),
            'notes'              => $data['notes'] ?? null,
            'created_at'         => date('Y-m-d H:i:s'),
            'updated_at'         => date('Y-m-d H:i:s'),
        ]);

        $bookingId = (int) $db->selectOne("SELECT LAST_INSERT_ID() AS id")['id'];

        EventBus::dispatch('private_match.booked', [
            'booking_id'  => $bookingId,
            'facility_id' => $facilityId,
            'amount'      => $totalCost,
            'member_id'   => !empty($data['member_id']) ? (int) $data['member_id'] : null,
        ]);

        return $bookingId;
    }

    public static function confirmBooking(int $bookingId): bool
    {
        $db = App::getInstance()->db();
        $booking = $db->selectOne("SELECT * FROM private_match_bookings WHERE id = ? AND status = 'pending'", [$bookingId]);
        if (!$booking) return false;

        $db->update('private_match_bookings', [
            'status'     => 'confirmed',
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$bookingId]);

        EventBus::dispatch('private_match.confirmed', [
            'booking_id'  => $bookingId,
            'facility_id' => (int) $booking['facility_id'],
        ]);

        return true;
    }

    public static function cancelBooking(int $bookingId, string $reason = ''): bool
    {
        $db = App::getInstance()->db();
        $db->update('private_match_bookings', [
            'status'           => 'cancelled',
            'cancelled_reason' => $reason,
            'updated_at'       => date('Y-m-d H:i:s'),
        ], '`id` = ? AND `status` IN (?, ?)', [$bookingId, 'pending', 'confirmed']);

        return true;
    }

    public static function completeBooking(int $bookingId): bool
    {
        $db = App::getInstance()->db();
        $db->update('private_match_bookings', [
            'status'     => 'completed',
            'updated_at' => date('Y-m-d H:i:s'),
        ], '`id` = ? AND `status` = ?', [$bookingId, 'confirmed']);

        return true;
    }

    public static function recordPayment(int $bookingId, float $amount): void
    {
        $db = App::getInstance()->db();
        $booking = $db->selectOne("SELECT * FROM private_match_bookings WHERE id = ?", [$bookingId]);
        if (!$booking) return;

        $newDeposit = (float) $booking['deposit_paid'] + $amount;
        $totalCost = (float) $booking['total_cost'];
        $paymentStatus = $newDeposit >= $totalCost ? 'paid' : ($newDeposit > 0 ? 'partial' : 'unpaid');

        $db->update('private_match_bookings', [
            'deposit_paid'   => $newDeposit,
            'payment_status' => $paymentStatus,
            'updated_at'     => date('Y-m-d H:i:s'),
        ], '`id` = ?', [$bookingId]);

        EventBus::dispatch('facility.entry_recorded', [
            'entry_id'    => $bookingId,
            'facility_id' => (int) $booking['facility_id'],
            'amount'      => $amount,
            'member_id'   => $booking['booked_by_member_id'] ? (int) $booking['booked_by_member_id'] : null,
            'booker_type' => $booking['booked_by_member_id'] ? 'member' : 'guest',
        ]);
    }
}
