<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Mtc\MercuryDataModels\PropertyCategory;

class EnforcePropertyCategoryRestriction
{
    /**
     * Guard the superadmin-only restriction for data modules (property
     * categories). Non-MTC users may not read, modify or delete a flagged
     * module - its definition or its records - and receive a 403. They also
     * may not set the flag themselves on writes (the value is forced off).
     * The category listing hides flagged modules via the query scope instead.
     */
    public function handle(Request $request, Closure $next)
    {
        $isMtc = $request->user()?->hasRole('mtc') === true;

        $category = $this->resolveCategory($request);

        if ($category instanceof PropertyCategory && $category->superadmin_only && !$isMtc) {
            return response([
                'message' => __('validation.not_allowed_to_modify_property_category'),
            ], 403);
        }

        // Only MTC users may set the flag; force it off on writes for everyone else.
        if (!$isMtc && in_array($request->method(), ['POST', 'PUT', 'PATCH'], true)) {
            $request->merge(['superadmin_only' => false]);
        }

        return $next($request);
    }

    /**
     * Resolve the target category from the route. Record routes bind
     * {category:slug}; definition routes bind {property_category} by id.
     * Route middleware may run before SubstituteBindings, so a param can be
     * either an already-resolved model or a raw slug/id value.
     */
    private function resolveCategory(Request $request): ?PropertyCategory
    {
        $bySlug = $request->route('category');
        if ($bySlug instanceof PropertyCategory) {
            return $bySlug;
        }
        if ($bySlug !== null) {
            return PropertyCategory::query()->where('slug', $bySlug)->first();
        }

        $byId = $request->route('property_category');
        if ($byId instanceof PropertyCategory) {
            return $byId;
        }
        if ($byId !== null) {
            return PropertyCategory::query()->find($byId);
        }

        return null;
    }
}
