<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;

/**
 * Enforce an active subscription for all tenant API routes.
 *
 * When a trial or paid subscription has passed its end date this middleware
 * lazily marks it as 'expired', then returns 402 Payment Required so the
 * frontend can show the "subscription expired" gate and redirect to billing.
 *
 * Routes listed in $except are always allowed through so the user can still
 * reach the billing page, notifications, and basic auth endpoints.
 */
class RequiresActiveSubscription
{
    /**
     * URI patterns (matched via Request::is()) that are exempt from the check.
     * Billing, notification, and core auth endpoints must always be reachable.
     */
    protected array $except = [
        'api/user',
        'api/logout',
        'api/email/*',
        'api/billing',
        'api/billing/*',
        'api/notifications',
        'api/notifications/*',
        'api/roles',
    ];

    public function handle(Request $request, Closure $next): mixed
    {
        // Allow GET /api/settings through so the app can load business name/logo
        if ($request->isMethod('GET') && $request->is('api/settings')) {
            return $next($request);
        }

        // Check exempt URI patterns
        if ($request->is(...$this->except)) {
            return $next($request);
        }

        $user = $request->user();

        if (!$user || !$user->organization_id) {
            return response()->json(['message' => 'Unauthenticated.'], 401);
        }

        // Platform admins (impersonating or otherwise) are never blocked
        if ($user->hasRole('super-admin')) {
            return $next($request);
        }

        $org          = $user->organization;
        $subscription = $org?->subscription;

        // No subscription at all → implicit free plan, allow through
        if (!$subscription) {
            return $next($request);
        }

        // Lazily expire overdue trials / active subscriptions
        $subscription->expireIfNeeded();

        // Allow currently-active subscriptions
        if ($subscription->isCurrentlyActive()) {
            return $next($request);
        }

        // Subscription is expired or cancelled — block with 402
        $message = match ($subscription->status) {
            'expired'   => 'Your subscription has expired. Please renew your plan to continue using the application.',
            'cancelled' => 'Your subscription was cancelled. Please choose a plan to restore access.',
            default     => 'No active subscription found. Please subscribe to a plan to continue.',
        };

        return response()->json([
            'message'              => $message,
            'subscription_expired' => true,
            'subscription_status'  => $subscription->status,
        ], 402);
    }
}
