<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Resources\BasicBasketProductDetailResource;
use App\Http\Resources\BasicBasketProductListResource;
use App\Models\BasicBasketProduct;
use App\Models\Store;
use App\Services\BasicBasketPriceService;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;

class BasicBasketProductController extends Controller
{
    public function __construct(
        private readonly BasicBasketPriceService $priceService
    ) {}

    /**
     * Listado paginado de productos de la canasta básica con precio más bajo disponible.
     *
     * Parámetros de query opcionales:
     *   - search    (string)  Busca por nombre, slug o categoría.
     *   - category  (string)  Filtra por categoría exacta (retrocompatibilidad).
     *   - product   (string)  Filtra por slug exacto de producto.
     *   - store     (string)  Filtra por slug de tienda.
     *   - per_page  (int)     Resultados por página (default 12, máx 48).
     *   - page      (int)     Número de página.
     */
    public function index(Request $request): AnonymousResourceCollection
    {
        $filters = $request->validate([
            'search' => ['sometimes', 'string', 'max:100'],
            'category' => ['sometimes', 'string', 'max:100'],
            'product' => ['sometimes', 'string', 'max:100'],
            'store' => ['sometimes', 'string', 'max:100'],
            'per_page' => ['sometimes', 'integer', 'min:1', 'max:'.BasicBasketPriceService::MAX_PER_PAGE],
        ]);

        $perPage = (int) ($filters['per_page'] ?? BasicBasketPriceService::DEFAULT_PER_PAGE);
        $paginator = $this->priceService->getProductListing($filters, $perPage);

        return BasicBasketProductListResource::collection($paginator);
    }

    /**
     * Detalle de un producto con precios por tienda y URL del botón "Ir al producto".
     */
    public function show(Request $request, string $slug): BasicBasketProductDetailResource|JsonResponse
    {
        $product = $this->priceService->getProductDetail($slug);

        if ($product === null) {
            return response()->json(['message' => 'Producto no encontrado.'], 404);
        }

        return new BasicBasketProductDetailResource($product);
    }

    /**
     * Opciones para los filtros del frontend:
     *   - products: todos los productos activos (slug + name) ordenados por nombre.
     *   - stores:   todas las tiendas activas (slug + name + logo_url) ordenadas por nombre.
     */
    public function filters(): JsonResponse
    {
        $products = BasicBasketProduct::query()
            ->active()
            ->orderBy('name')
            ->get(['slug', 'name']);

        $stores = Store::query()
            ->active()
            ->orderBy('name')
            ->get(['slug', 'name', 'logo_url'])
            ->map(fn (Store $store): array => [
                'slug' => $store->slug,
                'name' => $store->name,
                'logo_url' => $store->logo_url !== null ? url($store->logo_url) : null,
            ]);

        return response()->json([
            'data' => [
                'products' => $products,
                'stores' => $stores,
            ],
        ]);
    }
}
