<?php

namespace App\Services;

use App\Models\AppSetting;
use App\Models\FoodOrder;
use App\Models\GasOrder;
use App\Models\TaxiRequest;
use App\Models\TripRequest;
use App\Models\PassengerExtraServiceRequest;
use App\Models\User;
use App\Models\Wallet;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;

class PromotionalWheelService
{
    /**
     * يُستدعى عند إتمام طلب (طعام / غاز / تاكسي) لزيادة العداد العالمي
     * وعند كل N طلب (افتراضي 250) يُعلّم الطلب الحالي لعرض عجلة الحظ للراكب.
     */
    public static function onOrderCompleted(string $type, int $orderId, float $feeAmount): void
    {
        try {
            DB::transaction(function () use ($type, $orderId, $feeAmount) {
                $settings = AppSetting::query()->lockForUpdate()->first();
                if (!$settings) {
                    return;
                }

                $settings->increment('global_completed_orders_count');
                $settings->refresh();

                $count = (int) $settings->global_completed_orders_count;
                $interval = max(1, (int) ($settings->wheel_milestone_interval ?? 250));

                if ($count % $interval !== 0) {
                    return;
                }

                $payload = [
                    'wheel_milestone_pending' => true,
                    'wheel_promo_fee_amount' => round($feeAmount, 2),
                ];

                match ($type) {
                    'food' => FoodOrder::where('id', $orderId)->update($payload),
                    'gas' => GasOrder::where('id', $orderId)->update($payload),
                    'taxi' => TaxiRequest::where('id', $orderId)->update($payload),
                    'trip' => TripRequest::where('id', $orderId)->update($payload),
                    'extra_service' => PassengerExtraServiceRequest::where('id', $orderId)->update($payload),
                    default => null,
                };
            });
        } catch (\Throwable $e) {
            Log::error('PromotionalWheelService::onOrderCompleted: '.$e->getMessage());
        }
    }

    public static function spinForUser(User $user, string $orderType, int $orderId): array
    {
        return DB::transaction(function () use ($user, $orderType, $orderId) {
            $settings = AppSetting::query()->lockForUpdate()->first();
            if (!$settings) {
                throw new \RuntimeException('إعدادات التطبيق غير متوفرة');
            }

            $winning = max(1, min(12, (int) ($settings->wheel_winning_segment ?? 12)));

            $order = match ($orderType) {
                'food' => FoodOrder::query()->lockForUpdate()->findOrFail($orderId),
                'gas' => GasOrder::query()->lockForUpdate()->findOrFail($orderId),
                'taxi' => TaxiRequest::query()->lockForUpdate()->findOrFail($orderId),
                'trip' => TripRequest::query()->lockForUpdate()->findOrFail($orderId),
                'extra_service' => PassengerExtraServiceRequest::query()->lockForUpdate()->findOrFail($orderId),
                default => throw new \InvalidArgumentException('نوع الطلب غير مدعوم'),
            };

            if ($orderType === 'taxi') {
                $pid = (string) $order->passenger_id;
                $phoneMatch = trim((string) $order->passenger_phone) === trim((string) ($user->phone ?? ''));
                if ($pid !== (string) $user->id && ! $phoneMatch) {
                    abort(403, 'هذا الطلب لا يخصك');
                }
            } elseif ($orderType === 'trip') {
                if ((int) $order->passenger_id !== (int) $user->id) {
                    abort(403, 'هذا الطلب لا يخصك');
                }
            } elseif ($orderType === 'extra_service') {
                if ((int) $order->user_id !== (int) $user->id) {
                    abort(403, 'هذا الطلب لا يخصك');
                }
            } elseif ((int) $order->customer_id !== (int) $user->id) {
                abort(403, 'هذا الطلب لا يخصك');
            }

            if (!(bool) $order->wheel_milestone_pending) {
                throw new \RuntimeException('لا توجد عجلة مرتبطة بهذا الطلب');
            }

            if ($order->wheel_result !== null) {
                throw new \RuntimeException('تم تدوير العجلة مسبقاً لهذا الطلب');
            }

            $segment = random_int(1, 12);
            $order->wheel_result = $segment;
            $order->wheel_spun_at = now();
            $order->wheel_milestone_pending = false;
            $order->save();

            $won = ($segment === $winning);
            $credit = 0.0;

            if ($won) {
                $credit = (float) ($order->wheel_promo_fee_amount ?? 0);
                if ($credit > 0) {
                    $wallet = Wallet::getOrCreateForUser($user->id);
                    $wallet->addBalance(
                        $credit,
                        'wheel_promo',
                        $order::class,
                        (int) $order->id,
                        'مكافأة عجلة الحظ — طلب مجاني (القطاع '.$segment.')'
                    );
                }
            }

            return [
                'segment' => $segment,
                'winning_segment' => $winning,
                'won' => $won,
                'credited_amount' => $credit,
            ];
        });
    }
}
