<?php

namespace App\Http\Controllers;

use App\Models\ProductVariant;
use App\Services\CartService;
use App\Services\CheckoutService;
use App\Services\CouponService;
use App\Services\AnalyticsTracker;
use Illuminate\Http\Request;
use RuntimeException;

class CartController extends Controller
{
    public function index(CartService $cart, CouponService $coupons)
    {
        $quote = $this->couponQuote($cart, $coupons);

        return view('cart.index', [
            'items' => $cart->all(),
            'totalMinor' => $cart->totalMinor(),
            'couponCode' => $cart->couponCode(),
            'discountMinor' => $quote['discount_minor'],
            'payableMinor' => $quote['total_minor'],
        ]);
    }

    public function add(Request $request, ProductVariant $productVariant, CartService $cart, AnalyticsTracker $analytics)
    {
        $data = $request->validate([
            'quantity' => ['nullable', 'integer', 'min:1', 'max:99'],
        ]);

        $cart->add($productVariant, (int) ($data['quantity'] ?? 1));

        $analytics->track($request, 'add_to_cart', 'product_variant', $productVariant->id, [
            'quantity' => (int) ($data['quantity'] ?? 1),
            'sku' => $productVariant->sku,
            'cart_count' => $cart->count(),
        ]);

        if ($request->expectsJson()) {
            return response()->json($this->cartPayload($cart, 'تمت إضافة المنتج للسلة.'));
        }

        return redirect()->route('cart.index')->with('status', 'تمت إضافة المنتج للسلة.');
    }

    public function update(Request $request, ProductVariant $productVariant, CartService $cart)
    {
        $data = $request->validate([
            'quantity' => ['required', 'integer', 'min:0', 'max:99'],
        ]);

        $cart->update($productVariant, (int) $data['quantity']);

        if ($request->expectsJson()) {
            return response()->json($this->cartPayload($cart, 'تم تحديث السلة.'));
        }

        return back()->with('status', 'تم تحديث السلة.');
    }

    public function remove(ProductVariant $productVariant, CartService $cart)
    {
        $cart->remove($productVariant);

        if (request()->expectsJson()) {
            return response()->json($this->cartPayload($cart, 'تم حذف المنتج من السلة.'));
        }

        return back()->with('status', 'تم حذف المنتج من السلة.');
    }

    public function applyCoupon(Request $request, CartService $cart, CouponService $coupons)
    {
        $data = $request->validate([
            'coupon_code' => ['required', 'string', 'max:40'],
        ]);

        try {
            $coupons->quote($data['coupon_code'], $cart->all(), $request->user(), $request->user()?->email);
        } catch (RuntimeException $exception) {
            return back()->withErrors(['coupon' => $exception->getMessage()]);
        }

        $cart->applyCoupon($data['coupon_code']);

        if ($request->expectsJson()) {
            return response()->json($this->cartPayload($cart, 'تم تطبيق الكوبون.'));
        }

        return back()->with('status', 'تم تطبيق الكوبون.');
    }

    public function removeCoupon(CartService $cart)
    {
        $cart->removeCoupon();

        if (request()->expectsJson()) {
            return response()->json($this->cartPayload($cart, 'تم حذف الكوبون.'));
        }

        return back()->with('status', 'تم حذف الكوبون.');
    }

    public function checkout(Request $request, CartService $cart, CouponService $coupons, AnalyticsTracker $analytics)
    {
        $items = $cart->all();

        if ($items->isEmpty()) {
            return redirect()->route('cart.index')->withErrors(['cart' => 'السلة فارغة.']);
        }

        $analytics->track($request, 'checkout_start', 'cart', null, [
            'items' => $items->count(),
            'total_minor' => $cart->totalMinor(),
        ]);

        return view('cart.checkout', [
            'items' => $items,
            'totalMinor' => $cart->totalMinor(),
            'couponCode' => $cart->couponCode(),
            'quote' => $this->couponQuote($cart, $coupons),
        ]);
    }

    public function placeOrder(Request $request, CartService $cart, CheckoutService $checkoutService, AnalyticsTracker $analytics)
    {
        $payload = $request->validate([
            'customer_name' => ['required', 'string', 'max:120'],
            'customer_email' => ['nullable', 'email', 'max:190'],
            'player_id' => ['nullable', 'string', 'max:80'],
            'server' => ['nullable', 'string', 'max:80'],
            'notes' => ['nullable', 'string', 'max:500'],
            'payment_method' => ['required', 'in:manual,wallet,mock_gateway,online_gateway'],
            'coupon_code' => ['nullable', 'string', 'max:40'],
        ]);

        $payload['coupon_code'] = $payload['coupon_code'] ?? $cart->couponCode();

        try {
            $order = $checkoutService->createOrderFromCart($cart->all(), $payload, $request->user());
        } catch (RuntimeException $exception) {
            return back()->withErrors(['cart' => $exception->getMessage()])->withInput();
        }

        $analytics->track($request, 'order_created', 'order', $order->id, [
            'order_number' => $order->order_number,
            'total_minor' => $order->total_minor,
            'payment_method' => $order->payment_method,
        ]);

        $cart->clear();

        if ($order->payment_method === 'mock_gateway') {
            return redirect()->route('payments.mock.show', $order);
        }

        if ($order->payment_method === 'online_gateway') {
            return redirect()->route('payments.online.show', $order);
        }

        return redirect()->route('orders.show', $order)->with('status', 'تم إنشاء طلب السلة بنجاح.');
    }

    private function couponQuote(CartService $cart, CouponService $coupons): array
    {
        try {
            return $coupons->quote($cart->couponCode(), $cart->all(), request()->user(), request()->user()?->email);
        } catch (RuntimeException) {
            $cart->removeCoupon();

            return $coupons->quote(null, $cart->all(), request()->user(), request()->user()?->email);
        }
    }

    private function cartPayload(CartService $cart, string $message): array
    {
        return [
            'ok' => true,
            'message' => $message,
            'cart_count' => $cart->count(),
            'cart_total_minor' => $cart->totalMinor(),
            'cart_url' => route('cart.index'),
        ];
    }
}
