<?php
declare(strict_types=1);

namespace App\Modules\SportsActivity\Services;

use App\Core\App;

final class PricingCalculatorService
{
    public static function calculate(
        int $facilityUnitId,
        string $date,
        string $startTime,
        string $endTime,
        int $participantCount,
        bool|string $isMemberOrBookerType
    ): ?array {
        $bookerType = is_string($isMemberOrBookerType) ? $isMemberOrBookerType : ($isMemberOrBookerType ? 'member' : 'guest');
        $isMember = ($bookerType === 'member');
        $db = App::getInstance()->db();

        $unit = $db->selectOne(
            "SELECT fu.facility_id FROM sa_facility_units fu WHERE fu.id = ?",
            [$facilityUnitId]
        );

        if (!$unit) {
            return null;
        }

        $dayOfWeek = (int) date('w', strtotime($date));

        $bracket = $db->selectOne(
            "SELECT id, name_ar, bracket_type FROM sa_time_brackets
             WHERE facility_id = ? AND is_active = 1
             AND start_time <= ? AND end_time > ?
             AND JSON_CONTAINS(days_of_week_json, CAST(? AS JSON))
             ORDER BY bracket_type = 'peak' DESC
             LIMIT 1",
            [(int) $unit['facility_id'], $startTime, $startTime, (string) $dayOfWeek]
        );

        if (!$bracket) {
            return null;
        }

        $today = date('Y-m-d');
        $rule = $db->selectOne(
            "SELECT * FROM sa_pricing_rules
             WHERE facility_unit_id = ? AND time_bracket_id = ?
             AND group_size_min <= ? AND group_size_max >= ?
             AND effective_from <= ? AND (effective_to IS NULL OR effective_to >= ?)
             AND is_active = 1
             ORDER BY effective_from DESC
             LIMIT 1",
            [$facilityUnitId, (int) $bracket['id'], $participantCount, $participantCount, $today, $today]
        );

        if (!$rule) {
            return null;
        }

        if ($bookerType === 'organization' && !empty($rule['price_per_person_organization'])) {
            $pricePerPerson = (float) $rule['price_per_person_organization'];
        } else {
            $pricePerPerson = $isMember
                ? (float) $rule['price_per_person_member']
                : (float) $rule['price_per_person_nonmember'];
        }

        $durationSeconds = strtotime($endTime) - strtotime($startTime);
        $durationHours = $durationSeconds / 3600.0;

        $totalAmount = $pricePerPerson * $participantCount * $durationHours;

        return [
            'price_per_person'   => $pricePerPerson,
            'participant_count'  => $participantCount,
            'duration_hours'     => $durationHours,
            'total_amount'       => round($totalAmount, 2),
            'bracket_name'       => $bracket['name_ar'],
            'bracket_type'       => $bracket['bracket_type'],
            'is_member'          => $isMember,
            'booker_type'        => $bookerType,
            'rule_id'            => (int) $rule['id'],
        ];
    }
}
