<?php

namespace App\Services;

use App\Models\ProductVariant;
use App\Models\User;
use Illuminate\Support\Facades\Session;

class CartService
{
    protected PricingService $pricingService;
    protected PointsService $pointsService;

    public function __construct(PricingService $pricingService, PointsService $pointsService)
    {
        $this->pricingService = $pricingService;
        $this->pointsService = $pointsService;
    }

    /**
     * أضف variant إلى السلة. إذا كان موجوداً يتم زيادة الكمية.
     */
    public function addItem(int $variantId, int $qty = 1): void
    {
        $cart = $this->getCart();

        if (isset($cart[$variantId])) {
            $cart[$variantId]['quantity'] += $qty;
        } else {
            $variant = ProductVariant::with('product')->findOrFail($variantId);
            $cart[$variantId] = [
                'variant_id' => $variantId,
                'product_id' => $variant->product_id,
                'product_name' => $variant->product->name,
                'pattern_name' => $variant->pattern_name,
                'color' => $variant->color,
                'sku' => $variant->sku,
                'cost_price' => (float) $variant->cost_price,
                'fulfillment_type' => $variant->product->fulfillment_type,
                'lead_time_days' => $variant->lead_time_days,
                'stock' => $variant->stock,
                'quantity' => $qty,
            ];
        }

        $this->saveCart($cart);
    }

    /**
     * حدّث كمية variant في السلة.
     */
    public function updateQuantity(int $variantId, int $qty): void
    {
        $cart = $this->getCart();

        if ($qty <= 0) {
            unset($cart[$variantId]);
        } elseif (isset($cart[$variantId])) {
            $cart[$variantId]['quantity'] = $qty;
        }

        $this->saveCart($cart);
    }

    /**
     * احذف عنصر من السلة.
     */
    public function removeItem(int $variantId): void
    {
        $cart = $this->getCart();
        unset($cart[$variantId]);
        $this->saveCart($cart);
    }

    /**
     * فرّغ السلة بالكامل.
     */
    public function clear(): void
    {
        Session::forget('cart');
    }

    /**
     * أعد حساب كل الأسعار بناءً على شرائح المنتج الأب.
     * هذه الدالة الجوهرية: كل ما يتغير في السلة يُعاد حساب الكل.
     */
    public function recalculate(): CartSummary
    {
        $cart = $this->getCart();

        if (empty($cart)) {
            return new CartSummary();
        }

        $cartItems = array_values($cart);
        $prices = $this->pricingService->calculateCartPrices($cartItems);

        $variantIds = array_keys($cart);
        $variants = ProductVariant::whereIn('id', $variantIds)->get()->keyBy('id');

        $items = [];
        $subtotal = 0;
        $totalProfit = 0;

        foreach ($cart as $variantId => $item) {
            $variant = $variants[$variantId] ?? null;
            $imagePath = $variant ? ($variant->image_thumbnail ?? $variant->image_webp ?? $variant->image) : null;
            $priceInfo = $prices[$variantId] ?? null;
            $unitPrice = $priceInfo ? $priceInfo['unit_price'] : 0;
            $lineTotal = $unitPrice * $item['quantity'];
            $lineProfit = ($unitPrice - $item['cost_price']) * $item['quantity'];

            $items[] = [
                'variant_id' => $variantId,
                'product_id' => $item['product_id'],
                'product_name' => $item['product_name'],
                'pattern_name' => $item['pattern_name'],
                'color' => $item['color'],
                'sku' => $item['sku'],
                'quantity' => $item['quantity'],
                'unit_price' => $unitPrice,
                'cost_price' => $item['cost_price'],
                'line_total' => $lineTotal,
                'line_profit' => $lineProfit,
                'fulfillment_type' => $item['fulfillment_type'],
                'lead_time_days' => $item['lead_time_days'],
                'stock' => $item['stock'],
                'product_total_qty' => $priceInfo['product_total_qty'] ?? $item['quantity'],
                'tier' => $priceInfo['tier'] ?? null,
                'image_path' => $imagePath,
            ];

            $subtotal += $lineTotal;
            $totalProfit += $lineProfit;
        }

        $pointsEarned = $this->pointsService->calculateEarnedPoints($subtotal);

        $summary = new CartSummary();
        $summary->items = $items;
        $summary->subtotal = round($subtotal, 2);
        $summary->totalProfit = round($totalProfit, 2);
        $summary->pointsEarned = $pointsEarned;
        $summary->discountFromPoints = 0;
        $summary->pointsRedeemed = 0;
        $summary->total = $summary->subtotal;

        return $summary;
    }

    /**
     * أعد الحساب مع تطبيق استبدال نقاط.
     */
    public function recalculateWithRedemption(User $user, int $pointsToRedeem): CartSummary
    {
        $summary = $this->recalculate();

        if ($pointsToRedeem <= 0) {
            return $summary;
        }

        $maxRedeemable = $this->pointsService->getMaxRedeemablePoints($user, $summary->subtotal);
        $actualPoints = min($pointsToRedeem, $maxRedeemable);
        $discount = $this->pointsService->calculateRedemptionDiscount($actualPoints);

        $discount = min($discount, $summary->subtotal);

        $summary->pointsRedeemed = $actualPoints;
        $summary->discountFromPoints = round($discount, 2);
        $summary->total = round($summary->subtotal - $discount, 2);

        $summary->pointsEarned = $this->pointsService->calculateEarnedPoints($summary->total);

        return $summary;
    }

    /**
     * عدد العناصر في السلة.
     */
    public function count(): int
    {
        return count($this->getCart());
    }

    /**
     * إجمالي القطع في السلة.
     */
    public function totalQuantity(): int
    {
        $total = 0;
        foreach ($this->getCart() as $item) {
            $total += $item['quantity'];
        }
        return $total;
    }

    public function getCart(): array
    {
        return Session::get('cart', []);
    }

    protected function saveCart(array $cart): void
    {
        Session::put('cart', $cart);
    }
}
