<?php

declare(strict_types=1);

namespace App\Http\Controllers\Account;

use App\Http\Controllers\Controller;
use App\Models\CartItem;
use App\Models\Plan;
use App\Services\Billing\CartService;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Inertia\Inertia;
use Inertia\Response;

class CartController extends Controller
{
    public function __construct(
        private CartService $cartService,
    ) {}

    public function index(Request $request): Response
    {
        /** @var \App\Models\User $user */
        $user = $request->user();

        $items = $this->cartService->getItems($user);
        $total = $this->cartService->getTotal($user);

        // Compute per-item prices
        $itemsWithPrices = $items->map(function (CartItem $item): array {
            $unitPrice = $this->cartService->getItemPrice($item);

            return [
                'id' => $item->id,
                'plan_id' => $item->plan_id,
                'billing_cycle' => $item->billing_cycle,
                'quantity' => $item->quantity,
                'config_selections' => $item->config_selections,
                'coupon_code' => $item->coupon_code,
                'unit_price' => number_format($unitPrice, 2, '.', ''),
                'line_total' => number_format($unitPrice * $item->quantity, 2, '.', ''),
                'plan' => $item->plan ? [
                    'id' => $item->plan->id,
                    'name' => $item->plan->name,
                    'service_type' => $item->plan->service_type,
                    'description' => $item->plan->description,
                    'features' => $item->plan->features,
                ] : null,
            ];
        });

        return Inertia::render('Cart/Index', [
            'items' => $itemsWithPrices,
            'total' => number_format($total, 2, '.', ''),
            'itemCount' => $this->cartService->getItemCount($user),
        ]);
    }

    public function add(Request $request): RedirectResponse
    {
        $validated = $request->validate([
            'plan_id' => ['required', 'exists:plans,id'],
            'billing_cycle' => ['required', 'string', 'in:monthly,quarterly,semi_annual,annual'],
            'quantity' => ['sometimes', 'integer', 'min:1', 'max:10'],
            'config_selections' => ['nullable', 'array'],
            'coupon_code' => ['nullable', 'string', 'max:50'],
        ]);

        /** @var \App\Models\User $user */
        $user = $request->user();
        $plan = Plan::findOrFail($validated['plan_id']);

        if (! $plan->isAvailable()) {
            return redirect()->back()->with('error', 'This plan is not available.');
        }

        $this->cartService->addItem(
            userOrSession: $user,
            plan: $plan,
            cycle: $validated['billing_cycle'],
            qty: $validated['quantity'] ?? 1,
            config: $validated['config_selections'] ?? null,
            couponCode: $validated['coupon_code'] ?? null,
        );

        return redirect()->route('account.cart.index')
            ->with('success', "{$plan->name} has been added to your cart.");
    }

    public function update(Request $request, CartItem $cartItem): RedirectResponse
    {
        $validated = $request->validate([
            'quantity' => ['required', 'integer', 'min:1', 'max:10'],
        ]);

        /** @var \App\Models\User $user */
        $user = $request->user();

        // Verify ownership
        if ($cartItem->user_id !== $user->id) {
            abort(403);
        }

        $this->cartService->updateQuantity($cartItem->id, $validated['quantity']);

        return redirect()->route('account.cart.index')
            ->with('success', 'Cart updated.');
    }

    public function remove(Request $request, CartItem $cartItem): RedirectResponse
    {
        /** @var \App\Models\User $user */
        $user = $request->user();

        // Verify ownership
        if ($cartItem->user_id !== $user->id) {
            abort(403);
        }

        $this->cartService->removeItem($cartItem->id);

        return redirect()->route('account.cart.index')
            ->with('success', 'Item removed from cart.');
    }
}
