<?php

declare(strict_types=1);

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Crypt;
use App\Models\License;
use Illuminate\Contracts\Encryption\DecryptException;
use Inertia\Inertia;
use Inertia\Response;
use Illuminate\Http\RedirectResponse;

class LicenseController extends Controller
{
    /**
     * Display the license activation page.
     */
    public function showActivationPage(Request $request): Response|RedirectResponse
    {
        // If bypass applies, redirect to dashboard directly
        if ($this->shouldBypass($request)) {
            return redirect()->route('dashboard');
        }

        // Check if a valid active license signature already exists in the database
        $license = License::first();
        if ($license) {
            try {
                $payload = json_decode(Crypt::decryptString($license->signature), true);
                if ($payload && isset($payload['domain']) && $payload['domain'] === $request->getHost()) {
                    return redirect()->route('dashboard');
                }
            } catch (DecryptException) {
                // Signature is invalid (app key changed or DB tampered), proceed to activation page
            }
        }

        return Inertia::render('Auth/ActivateLicense', [
            'domain' => $request->getHost(),
            'status' => session('status'),
            'error' => session('error'),
        ]);
    }

    /**
     * Process license activation.
     */
    public function activate(Request $request): RedirectResponse
    {
        $request->validate([
            'license_code' => ['required', 'string', 'regex:/^(RL|CP)-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}-[A-Z0-9]{4}$/i'],
        ], [
            'license_code.regex' => 'The license code format must be RL-XXXX-XXXX-XXXX-XXXX or CP-XXXX-XXXX-XXXX-XXXX.',
        ]);

        $licenseCode = strtoupper($request->input('license_code'));

        try {
            // Send request to licensing server
            $response = Http::timeout(10)
                ->when($this->shouldBypassSsl($request), function ($client) {
                    return $client->withoutVerifying();
                })
                ->post('https://radhcloud.com/api/licenses/validate', [
                    'license_code' => $licenseCode,
                ]);

            // Handle API responses
            if ($response->successful()) { // 200 OK
                $payload = [
                    'license_code' => $licenseCode,
                    'domain' => $request->getHost(),
                    'activated_at' => now()->toIso8601String(),
                ];

                $encryptedSignature = Crypt::encryptString(json_encode($payload));

                // Save to database, replacing any old license record
                License::truncate();
                License::create([
                    'license_code' => $licenseCode,
                    'signature' => $encryptedSignature,
                    'activated_at' => now(),
                ]);

                return redirect()->route('dashboard')->with('success', 'License activated successfully!');
            }

            if ($response->status() === 400) {
                return redirect()->back()->withErrors([
                    'license_code' => 'This license has already been used on another activation.',
                ]);
            }

            if ($response->status() === 404) {
                return redirect()->back()->withErrors([
                    'license_code' => 'The license code is incorrect or unregistered.',
                ]);
            }

            return redirect()->back()->withErrors([
                'license_code' => 'Unexpected response from licensing server. Please try again.',
            ]);

        } catch (\Throwable $e) {
            return redirect()->back()->withErrors([
                'license_code' => 'Could not connect to the licensing server: ' . $e->getMessage(),
            ]);
        }
    }

    /**
     * Determine if the request environment/host should bypass license checks.
     */
    protected function shouldBypass(Request $request): bool
    {
        // Bypass for local environment
        if (app()->environment('local')) {
            return true;
        }

        $host = $request->getHost();

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

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

        return false;
    }

    /**
     * Determine if cURL SSL certificate verification should be bypassed (local networks/dev hosts).
     */
    protected function shouldBypassSsl(Request $request): bool
    {
        if (app()->environment('local', 'testing', 'demo')) {
            return true;
        }

        $host = $request->getHost();

        // 1. Loopback addresses
        if (in_array($host, ['localhost', '127.0.0.1', '[::1]'])) {
            return true;
        }

        // 2. Local domains
        if (str_ends_with($host, '.test') || str_ends_with($host, '.local')) {
            return true;
        }

        // 3. Private IP Address ranges
        if (filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
            // 192.168.x.x
            if (str_starts_with($host, '192.168.')) {
                return true;
            }
            // 10.x.x.x
            if (str_starts_with($host, '10.')) {
                return true;
            }
            // 172.16.x.x - 172.31.x.x
            if (preg_match('/^172\.(1[6-9]|2[0-9]|3[0-1])\./', $host)) {
                return true;
            }
        }

        return false;
    }
}
