<?php

namespace Modules\Routing\Http\Controllers;

use Illuminate\Http\Request;
use Illuminate\Http\Resources\Json\AnonymousResourceCollection;
use Illuminate\Routing\Controller;
use Illuminate\Support\Facades\Cache;
use Modules\Routing\Http\Resources\EvRouteResource;
use Modules\Routing\Http\Resources\RoutePricingResource;
use Modules\Routing\Http\Resources\RouteTimeSlotResource;
use Modules\Routing\Models\EvRoute;

class EvRouteController extends Controller
{
    /**
     * @var list<string>
     */
    private const EAGER_LOADS = ['company', 'fromDestination', 'toDestination', 'timeSlots', 'pricing'];

    private const CACHE_TAG = 'routes';

    private const CACHE_TTL_MINUTES = 5;

    public function index(Request $request): AnonymousResourceCollection
    {
        $filters = $request->only(['company', 'from', 'to', 'date']);

        $routes = Cache::tags(self::CACHE_TAG)->remember(
            'routes:index:'.md5(json_encode($filters)),
            now()->addMinutes(self::CACHE_TTL_MINUTES),
            fn () => EvRoute::query()
                ->where('is_active', true)
                ->when($request->filled('company'), fn ($query) => $query->where('ev_company_id', $request->integer('company')))
                ->when($request->filled('from'), fn ($query) => $query->where('from_destination_id', $request->integer('from')))
                ->when($request->filled('to'), fn ($query) => $query->where('to_destination_id', $request->integer('to')))
                // `date` is accepted for forward-compatibility with future per-date capacity
                // checks (domain.md §7), but v1 has no route-level calendar to filter against.
                ->with(self::EAGER_LOADS)
                ->get(),
        );

        return EvRouteResource::collection($routes);
    }

    public function show(EvRoute $route): EvRouteResource
    {
        abort_unless($route->is_active, 404);

        $route = Cache::tags(self::CACHE_TAG)->remember(
            "routes:show:{$route->id}",
            now()->addMinutes(self::CACHE_TTL_MINUTES),
            fn () => $route->load(self::EAGER_LOADS),
        );

        return new EvRouteResource($route);
    }

    public function pricing(EvRoute $route): AnonymousResourceCollection
    {
        abort_unless($route->is_active, 404);

        $pricing = Cache::tags(self::CACHE_TAG)->remember(
            "routes:pricing:{$route->id}",
            now()->addMinutes(self::CACHE_TTL_MINUTES),
            fn () => $route->pricing()->get(),
        );

        return RoutePricingResource::collection($pricing);
    }

    public function timeSlots(EvRoute $route): AnonymousResourceCollection
    {
        abort_unless($route->is_active, 404);

        $timeSlots = Cache::tags(self::CACHE_TAG)->remember(
            "routes:time-slots:{$route->id}",
            now()->addMinutes(self::CACHE_TTL_MINUTES),
            fn () => $route->timeSlots()->get(),
        );

        return RouteTimeSlotResource::collection($timeSlots);
    }
}
