<?php

declare(strict_types=1);

namespace App\Services;

use App\Models\Order;
use Illuminate\Http\Request;

/**
 * Control de acceso en sesión a la página de confirmación de checkout y al POST de pago.
 *
 * Problema que resuelve:
 * - El usuario puede tener varias órdenes pendientes (pestañas distintas); guardar solo “el último id”
 *   en sesión haría que una pestaña perdiera permiso para pagar.
 *
 * Enfoque:
 * - Mantener un **conjunto** de ids de orden autorizados en sesión (`ALLOWED_ORDER_IDS_KEY`).
 * - Mantener `rt_checkout_order_id` por compatibilidad con código que esperaba un único id (legacy).
 *
 * Quién puede ver `/confirmacion/{uuid}`:
 * - El usuario autenticado si la orden es suya (`orders.user_id`).
 * - O la sesión que creó esa orden (ids permitidos o legacy).
 */
final class CheckoutOrderSession
{
    /** Clave de sesión: mapa order_id => true para órdenes que esta sesión puede gestionar. */
    public const ALLOWED_ORDER_IDS_KEY = 'rt_checkout_allowed_order_ids';

    /**
     * Registra la orden como “propiedad” de esta sesión de navegador (tras crearla o al volver a ella).
     *
     * Debe llamarse después de crear la orden y también al cargar confirmación si `canAccess` pasó,
     * para refrescar la lista de ids permitidos.
     */
    public static function grant(Request $request, Order $order): void
    {
        $ids = $request->session()->get(self::ALLOWED_ORDER_IDS_KEY, []);
        if (! is_array($ids)) {
            $ids = [];
        }
        $ids[(int) $order->id] = true;
        $request->session()->put(self::ALLOWED_ORDER_IDS_KEY, $ids);
        // Compatibilidad: algunos flujos solo leen esta clave singular.
        $request->session()->put('rt_checkout_order_id', (int) $order->id);
    }

    /**
     * Indica si el request actual puede operar sobre esta orden (ver confirmación o pagar).
     *
     * Orden de comprobación:
     * 1. Usuario logueado y dueño de la orden según `user_id`.
     * 2. Coincidencia con la clave legacy `rt_checkout_order_id`.
     * 3. Presencia del id en el mapa `ALLOWED_ORDER_IDS_KEY`.
     */
    public static function canAccess(Request $request, Order $order): bool
    {
        $user = $request->user();
        if ($user !== null && $order->user_id !== null && (int) $order->user_id === (int) $user->id) {
            return true;
        }

        $legacy = (int) $request->session()->get('rt_checkout_order_id');
        if ($legacy === (int) $order->id) {
            return true;
        }

        $ids = $request->session()->get(self::ALLOWED_ORDER_IDS_KEY, []);

        return is_array($ids) && ! empty($ids[(int) $order->id]);
    }
}
