<?php

declare(strict_types=1);

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Crypt;
use App\Models\License;
use Illuminate\Contracts\Encryption\DecryptException;
use Symfony\Component\HttpFoundation\Response;

class CheckLicense
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function handle(Request $request, Closure $next): Response
    {
        if ($this->shouldBypassLicenseCheck($request)) {
            return $next($request);
        }

        $license = License::first();
        if (!$license) {
            return redirect()->route('license.activate')->with('error', 'License activation is required for production.');
        }

        try {
            $payload = json_decode(Crypt::decryptString($license->signature), true);
            
            if (!$payload || !isset($payload['domain']) || $payload['domain'] !== $request->getHost()) {
                return redirect()->route('license.activate')->with('error', 'License is invalid for this domain.');
            }
        } catch (DecryptException) {
            return redirect()->route('license.activate')->with('error', 'License signature verification failed (encryption key changed or database tampered).');
        }

        return $next($request);
    }

    /**
     * Determine if the request should bypass the license check.
     */
    protected function shouldBypassLicenseCheck(Request $request): bool
    {
        // 1. Bypass if app environment is local or demo
        if (app()->environment('local', 'demo')) {
            return true;
        }

        // 2. Bypass if app environment is testing
        if (app()->environment('testing') && config('app.env') !== 'production') {
            return true;
        }

        $host = $request->getHost();

        // 3. Bypass for localhost and 127.0.0.1
        if (in_array($host, ['localhost', '127.0.0.1'])) {
            return true;
        }

        // 4. Bypass for domains ending in .test or .local
        if (str_ends_with($host, '.test') || str_ends_with($host, '.local')) {
            return true;
        }

        return false;
    }
}
