<?php

namespace App\Http\Middleware;

use App\Domains\Billing\Actions\SyncTenantLifecycleAction;
use App\Domains\Billing\Models\Subscription;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;

class EnsureSubscriptionIsActive
{
    public function __construct(
        protected SyncTenantLifecycleAction $syncTenantLifecycle,
    ) {
    }

    public function handle(Request $request, Closure $next): Response
    {
        $user = $request->user();
        $tenant = $user?->tenant;

        if (! $tenant) {
            return $next($request);
        }

        if ($this->isBillingRoute($request)) {
            return $next($request);
        }

        /** @var Subscription|null $subscription */
        $subscription = Subscription::query()
            ->where('tenant_id', $tenant->getKey())
            ->latest('created_at')
            ->first();

        $expired = $subscription
            && $subscription->ends_at
            && now()->greaterThanOrEqualTo($subscription->ends_at)
            && in_array($subscription->status, ['active', 'paid', 'succeeded', 'past_due', 'failed', 'cancelled'], true);

        if (! $expired) {
            return $next($request);
        }

        $this->syncTenantLifecycle->execute($tenant);

        if ($request->expectsJson() || $request->is('api/*')) {
            return response()->json([
                'message' => 'Subscription expired. Please pay your billing invoice to unlock the workspace.',
                'code' => 'subscription_expired',
            ], 402);
        }

        return redirect()
            ->route('settings.billing')
            ->with('status', 'Subscription expired. Please pay your latest invoice to unlock the workspace.');
    }

    private function isBillingRoute(Request $request): bool
    {
        $name = (string) $request->route()?->getName();

        if ($name === 'settings.billing') {
            return true;
        }

        return $request->is('api/billing/portal')
            || $request->is('api/billing/portal/upgrade')
            || $request->is('api/payment/providers')
            || $request->is('api/payment/providers/*')
            || $request->is('api/admin/*');
    }
}
