<?php

namespace App\Services;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Log;

class LicenseService
{
    private const CACHE_KEY  = '_tmit_lic';
    private const GRACE_KEY  = '_tmit_lic_grace';

    public function isValid(): bool
    {
        // Primary cache (24h) — avoid hitting server every request
        if (Cache::has(self::CACHE_KEY)) {
            return (bool) Cache::get(self::CACHE_KEY);
        }

        $serverUrl = config('license.server_url');

        // Bypass if URL is empty or clearly a placeholder — allow access
        if (empty($serverUrl) || $this->isPlaceholderUrl($serverUrl)) {
            return true;
        }

        try {
            $valid = $this->queryServer($serverUrl);

            Cache::put(self::CACHE_KEY, $valid, config('license.cache_ttl', 86400));

            if ($valid) {
                // Refresh grace period whenever we get a valid response
                Cache::put(self::GRACE_KEY, true, config('license.grace_ttl', 604800));
            } else {
                // Definitive invalid — clear grace cache immediately
                Cache::forget(self::GRACE_KEY);
            }

            return $valid;

        } catch (\Exception $e) {
            // Server unreachable — fall back to grace cache
            Log::warning('[License] Server unreachable: ' . $e->getMessage());
            return (bool) Cache::get(self::GRACE_KEY, false);
        }
    }

    private function isPlaceholderUrl(string $url): bool
    {
        $placeholders = [
            'yourdomain.com',
            'yourlicenseserver.com',
            'example.com',
            'your-server.com',
        ];
        foreach ($placeholders as $p) {
            if (str_contains($url, $p)) {
                return true;
            }
        }
        return false;
    }

    private function queryServer(string $serverUrl): bool
    {
        $domain = request()->getHost();
        $domain = preg_replace('/^www\./i', '', strtolower($domain));
        $domain = explode(':', $domain)[0]; // strip port

        $response = Http::timeout(5)
            ->withoutVerifying() // allow self-signed SSL on license server
            ->get($serverUrl, [
                'domain' => $domain,
                'code'   => config('license.purchase_code', ''),
                'secret' => config('license.secret', ''),
            ]);

        if ($response->successful()) {
            $data = $response->json();
            return (bool) ($data['valid'] ?? false);
        }

        // Non-2xx response counts as server error — use grace
        throw new \RuntimeException('License server returned HTTP ' . $response->status());
    }

    public function clearCache(): void
    {
        Cache::forget(self::CACHE_KEY);
        Cache::forget(self::GRACE_KEY);
    }

    public function status(): array
    {
        $serverUrl = config('license.server_url');
        $domain    = request()->getHost();
        $domain    = preg_replace('/^www\./i', '', strtolower($domain));

        return [
            'domain'         => $domain,
            'server_url'     => $serverUrl ?: '(not configured)',
            'cached_valid'   => Cache::get(self::CACHE_KEY, null),
            'grace_active'   => Cache::has(self::GRACE_KEY),
            'cache_ttl_left' => Cache::has(self::CACHE_KEY) ? 'cached' : 'expired',
        ];
    }
}
