<?php

namespace App\Services;

use App\Models\Coupon;
use App\Models\CouponRedemption;
use App\Models\User;
use Illuminate\Support\Facades\DB;

class CouponService
{
    public function validate(string $code, ?User $user, float $cartSubtotal): array
    {
        $coupon = Coupon::where('code', strtoupper($code))
            ->active()
            ->first();

        if (!$coupon) {
            return [
                'valid' => false,
                'error' => 'Invalid or expired coupon code.',
            ];
        }

        // Check minimum cart value
        if ($coupon->min_cart_value && $cartSubtotal < $coupon->min_cart_value) {
            return [
                'valid' => false,
                'error' => "Minimum cart value of ₹{$coupon->min_cart_value} required.",
            ];
        }

        // Check usage limit
        if ($coupon->usage_limit) {
            $totalUsage = CouponRedemption::where('coupon_id', $coupon->id)->count();
            if ($totalUsage >= $coupon->usage_limit) {
                return [
                    'valid' => false,
                    'error' => 'Coupon usage limit reached.',
                ];
            }
        }

        // Check per-user usage limit
        if ($user && $coupon->usage_per_user) {
            $userUsage = CouponRedemption::where('coupon_id', $coupon->id)
                ->where('user_id', $user->id)
                ->count();

            if ($userUsage >= $coupon->usage_per_user) {
                return [
                    'valid' => false,
                    'error' => 'You have already used this coupon the maximum number of times.',
                ];
            }
        }

        $discount = $this->calculateDiscount($coupon, $cartSubtotal);

        return [
            'valid' => true,
            'coupon' => $coupon,
            'discount' => $discount,
        ];
    }

    public function calculateDiscount(Coupon $coupon, float $subtotal): float
    {
        if ($coupon->type === 'percentage') {
            $discount = ($subtotal * $coupon->value) / 100;

            if ($coupon->max_discount) {
                $discount = min($discount, (float) $coupon->max_discount);
            }
        } else {
            // flat discount
            $discount = (float) $coupon->value;

            if ($coupon->max_discount) {
                $discount = min($discount, (float) $coupon->max_discount);
            }
        }

        // Discount cannot exceed subtotal
        return min($discount, $subtotal);
    }

    public function getAvailableCoupons(?User $user, float $cartSubtotal): array
    {
        $coupons = Coupon::active()->get();
        $availableCoupons = [];

        foreach ($coupons as $coupon) {
            $isEligible = true;
            $eligibilityReason = null;

            // Check minimum cart value
            if ($coupon->min_cart_value && $cartSubtotal < $coupon->min_cart_value) {
                $isEligible = false;
                $eligibilityReason = "Minimum cart value of ₹{$coupon->min_cart_value} required.";
            }

            // Check usage limit
            if ($isEligible && $coupon->usage_limit) {
                $totalUsage = CouponRedemption::where('coupon_id', $coupon->id)->count();
                if ($totalUsage >= $coupon->usage_limit) {
                    continue;
                }
            }

            // Check per-user usage limit
            if ($isEligible && $user && $coupon->usage_per_user) {
                $userUsage = CouponRedemption::where('coupon_id', $coupon->id)
                    ->where('user_id', $user->id)
                    ->count();

                if ($userUsage >= $coupon->usage_per_user) {
                    continue;
                }
            }

            // Calculate discount preview (even for ineligible coupons)
            $discount = $this->calculateDiscount($coupon, $cartSubtotal);

            $availableCoupons[] = [
                'id' => $coupon->id,
                'code' => $coupon->code,
                'type' => $coupon->type,
                'value' => $coupon->value,
                'min_cart_value' => $coupon->min_cart_value,
                'max_discount' => $coupon->max_discount,
                'discount_preview' => $discount,
                'is_eligible' => $isEligible,
                'eligibility_reason' => $eligibilityReason,
            ];
        }

        return $availableCoupons;
    }

    public function recordRedemption(Coupon $coupon, ?User $user, int $orderId): void
    {
        CouponRedemption::create([
            'coupon_id' => $coupon->id,
            'user_id' => $user?->id,
            'order_id' => $orderId,
            'used_at' => now(),
        ]);
    }
}
