<?php

namespace App\Services;

use App\Models\AppSetting;
use App\Models\DriverCashbackTransaction;
use App\Models\DriverCashbackWallet;
use App\Models\DriverReferral;
use App\Models\PartnerWallet;
use App\Models\TaxiRequest;
use App\Models\Trip;
use App\Models\TripRequest;
use Illuminate\Support\Facades\DB;

/**
 * خدمة محفظة الكاش باك للسائقين
 * مستويات النسبة | مكافأة المواظبة | مكافأة التقييم | مكافأة الدعوات
 */
class DriverCashbackService
{
    public static function getOrCreateWallet(int $driverId): DriverCashbackWallet
    {
        $wallet = DriverCashbackWallet::where('driver_id', $driverId)->first();
        if ($wallet) {
            return $wallet;
        }
        return DriverCashbackWallet::create([
            'driver_id' => $driverId,
            'balance' => 0,
        ]);
    }

    /**
     * إضافة كاش باك عند إتمام رحلة (TripRequest أو Trip)
     */
    public static function addCashbackForCompletedTrip(int $driverId, float $fare, ?int $tripRequestId = null, ?int $tripId = null, ?float $driverRating = null): ?float
    {
        $settings = AppSetting::first();
        if (!$settings || !($settings->cashback_enabled ?? true)) {
            return null;
        }

        $wallet = self::getOrCreateWallet($driverId);
        $today = now()->toDateString();

        // عدد رحلات اليوم المكتملة (تشمل الرحلة الحالية لأنها تُحدّث قبل استدعاء هذه الدالة)
        $todayTripsCount = TripRequest::where('driver_id', $driverId)
            ->where('status', 'completed')
            ->whereDate('updated_at', $today)
            ->count()
            + Trip::where('driver_id', $driverId)
                ->where('status', 'completed')
                ->whereDate('updated_at', $today)
                ->count()
            + TaxiRequest::where('driver_id', $driverId)
                ->where('status', 'completed')
                ->whereDate('updated_at', $today)
                ->count();

        // نسبة الكاش باك حسب مستوى الرحلات (كل رحلة تحصل على النسبة الحالية)
        $level1 = (int) ($settings->cashback_level_1_trips ?? 5);
        $level2 = (int) ($settings->cashback_level_2_trips ?? 10);
        $level3 = (int) ($settings->cashback_level_3_trips ?? 15);
        $percent1 = (float) ($settings->cashback_level_1_percent ?? 5);
        $percent2 = (float) ($settings->cashback_level_2_percent ?? 6);
        $percent3 = (float) ($settings->cashback_level_3_percent ?? 8);
        $percent0 = (float) ($settings->cashback_base_percent ?? 4); // 1-4 رحلات

        $basePercent = $todayTripsCount >= $level3 ? $percent3 : ($todayTripsCount >= $level2 ? $percent2 : ($todayTripsCount >= $level1 ? $percent1 : ($todayTripsCount >= 1 ? $percent0 : 0)));

        if ($basePercent <= 0) {
            return null;
        }

        // مكافأة التقييم (4.8+ = +1%)
        $ratingBonus = 0;
        if ($driverRating !== null && $driverRating >= (float) ($settings->cashback_rating_threshold ?? 4.80)) {
            $ratingBonus = (float) ($settings->cashback_rating_bonus_percent ?? 1);
        } elseif ($driverRating === null && $tripId) {
            $trip = Trip::find($tripId);
            if ($trip && $trip->driver_rating >= (float) ($settings->cashback_rating_threshold ?? 4.80)) {
                $ratingBonus = (float) ($settings->cashback_rating_bonus_percent ?? 1);
            }
        }

        $totalPercent = $basePercent + $ratingBonus;
        $cashbackAmount = round($fare * ($totalPercent / 100), 2);

        if ($cashbackAmount <= 0) {
            return null;
        }

        return DB::transaction(function () use ($wallet, $cashbackAmount, $tripRequestId, $tripId, $basePercent, $ratingBonus, $today, $settings, $driverId, $fare) {
            $wallet->refresh();
            $balanceAfter = (float) $wallet->balance + $cashbackAmount;

            $wallet->update([
                'balance' => $balanceAfter,
                'first_deposit_at' => $wallet->first_deposit_at ?? now(),
                'last_cashback_date' => $today,
                'consecutive_days' => self::calculateConsecutiveDays($wallet, $today),
            ]);

            $desc = "كاش باك رحلة ({$basePercent}%";
            if ($ratingBonus > 0) {
                $desc .= " + {$ratingBonus}% تقييم ممتاز";
            }
            $desc .= ')';

            DriverCashbackTransaction::create([
                'cashback_wallet_id' => $wallet->id,
                'type' => DriverCashbackTransaction::TYPE_TRIP_CASHBACK,
                'amount' => $cashbackAmount,
                'balance_after' => $balanceAfter,
                'source' => $tripRequestId ? 'trip_request' : ($tripId ? 'trip' : null),
                'source_id' => $tripRequestId ?? $tripId,
                'description' => $desc,
                'meta' => ['base_percent' => $basePercent, 'rating_bonus' => $ratingBonus],
            ]);

            // مكافأة المواظبة (7 أيام متتالية = +2% على إجمالي الأسبوع)
            self::checkContinuityBonus($wallet, $settings);

            // مكافأة الإحالة (للمُحيل إذا كان السائق مُدعى)
            self::addReferralCashbackForReferredTrip($driverId, $fare);

            return $cashbackAmount;
        });
    }

    protected static function calculateConsecutiveDays(DriverCashbackWallet $wallet, string $today): int
    {
        $last = $wallet->last_cashback_date?->format('Y-m-d');
        if (!$last) {
            return 1;
        }
        $lastDate = \Carbon\Carbon::parse($last);
        $todayDate = \Carbon\Carbon::parse($today);
        $diff = $lastDate->diffInDays($todayDate);
        if ($diff === 0) {
            return $wallet->consecutive_days;
        }
        if ($diff === 1) {
            return $wallet->consecutive_days + 1;
        }
        return 1;
    }

    protected static function checkContinuityBonus(DriverCashbackWallet $wallet, AppSetting $settings): void
    {
        $requiredDays = (int) ($settings->cashback_continuity_days ?? 7);
        if ($wallet->consecutive_days < $requiredDays) {
            return;
        }

        $weekStart = now()->startOfWeek();
        $transactions = DriverCashbackTransaction::where('cashback_wallet_id', $wallet->id)
            ->where('type', DriverCashbackTransaction::TYPE_TRIP_CASHBACK)
            ->where('created_at', '>=', $weekStart)
            ->get();

        $weekTripTotal = $transactions->sum('amount');
        $bonusPercent = (float) ($settings->cashback_continuity_bonus_percent ?? 2);
        $bonusAmount = round($weekTripTotal * ($bonusPercent / 100), 2);

        if ($bonusAmount <= 0) {
            return;
        }

        $alreadyPaid = DriverCashbackTransaction::where('cashback_wallet_id', $wallet->id)
            ->where('type', DriverCashbackTransaction::TYPE_CONTINUITY_BONUS)
            ->where('created_at', '>=', $weekStart)
            ->exists();

        if ($alreadyPaid) {
            return;
        }

        $wallet->refresh();
        $balanceAfter = (float) $wallet->balance + $bonusAmount;
        $wallet->update(['balance' => $balanceAfter]);

        DriverCashbackTransaction::create([
            'cashback_wallet_id' => $wallet->id,
            'type' => DriverCashbackTransaction::TYPE_CONTINUITY_BONUS,
            'amount' => $bonusAmount,
            'balance_after' => $balanceAfter,
            'description' => "مكافأة مواظبة {$requiredDays} أيام (+{$bonusPercent}%)",
            'meta' => ['week_total' => $weekTripTotal],
        ]);
    }

    /**
     * إضافة كاش باك للمُحيل عند رحلة السائق المُدعى
     * يُستدعى من addCashbackForCompletedTrip
     */
    public static function addReferralCashbackForReferredTrip(int $referredDriverId, float $fare): ?float
    {
        $referral = DriverReferral::where('referred_driver_id', $referredDriverId)
            ->where('bonus_months_remaining', '>', 0)
            ->first();

        if (!$referral) {
            return null;
        }

        $settings = AppSetting::first();
        $percent = (float) ($settings->cashback_referral_percent ?? 5);
        $amount = round($fare * ($percent / 100), 2);

        if ($amount <= 0) {
            return null;
        }

        $referrerWallet = self::getOrCreateWallet($referral->referrer_driver_id);

        return DB::transaction(function () use ($referrerWallet, $amount, $referral) {
            $referrerWallet->refresh();
            $balanceAfter = (float) $referrerWallet->balance + $amount;
            $referrerWallet->update([
                'balance' => $balanceAfter,
                'first_deposit_at' => $referrerWallet->first_deposit_at ?? now(),
            ]);

            DriverCashbackTransaction::create([
                'cashback_wallet_id' => $referrerWallet->id,
                'type' => DriverCashbackTransaction::TYPE_REFERRAL_BONUS,
                'amount' => $amount,
                'balance_after' => $balanceAfter,
                'source' => 'driver_referral',
                'source_id' => $referral->id,
                'description' => 'مكافأة إحالة سائق',
                'meta' => ['referred_driver_id' => $referral->referred_driver_id],
            ]);

            return $amount;
        });
    }

    /**
     * تحويل الكاش باك للمحفظة الرئيسية
     */
    public static function transferToMainWallet(int $driverId): array
    {
        $wallet = self::getOrCreateWallet($driverId);
        $balance = (float) $wallet->balance;

        if ($balance <= 0) {
            return ['success' => false, 'message' => 'لا يوجد رصيد للتحويل'];
        }

        $settings = AppSetting::first();
        $lockDays = (int) ($settings->cashback_lock_days ?? 30);
        $penaltyPercent = (float) ($settings->cashback_early_transfer_penalty_percent ?? 20);

        $isEarly = !$wallet->canTransfer();
        $transferAmount = $balance;

        if ($isEarly) {
            $penalty = round($balance * ($penaltyPercent / 100), 2);
            $transferAmount = $balance - $penalty;
        }

        if ($transferAmount <= 0) {
            return ['success' => false, 'message' => 'المبلغ بعد الخصم غير كافٍ'];
        }

        return DB::transaction(function () use ($wallet, $balance, $transferAmount, $isEarly, $penaltyPercent) {
            $mainWallet = PartnerWallet::getOrCreateFor(PartnerWallet::OWNER_TYPE_DRIVER, $wallet->driver_id);

            $wallet->update(['balance' => 0]);

            if ($isEarly) {
                $penaltyAmount = $balance - $transferAmount;
                DriverCashbackTransaction::create([
                    'cashback_wallet_id' => $wallet->id,
                    'type' => DriverCashbackTransaction::TYPE_EARLY_PENALTY,
                    'amount' => -$penaltyAmount,
                    'balance_after' => 0,
                    'description' => "خصم تحويل مبكر ({$penaltyPercent}%)",
                ]);
            }

            DriverCashbackTransaction::create([
                'cashback_wallet_id' => $wallet->id,
                'type' => DriverCashbackTransaction::TYPE_TRANSFER_TO_WALLET,
                'amount' => -$balance,
                'balance_after' => 0,
                'description' => 'تحويل للمحفظة الرئيسية',
            ]);

            \App\Services\PartnerWalletService::topUp(
                $mainWallet->id,
                $transferAmount,
                'cashback_transfer',
                'cashback_' . $wallet->id . '_' . now()->timestamp,
                'تحويل من محفظة الكاش باك'
            );

            return [
                'success' => true,
                'amount' => $transferAmount,
                'penalty' => $isEarly ? $balance - $transferAmount : 0,
                'message' => $isEarly
                    ? "تم التحويل مع خصم {$penaltyPercent}% للتحويل المبكر"
                    : 'تم التحويل بنجاح',
            ];
        });
    }
}
