<?php

namespace App\Licensing\Services;

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

/**
 * License Validator (Lixvalid)
 * Handles license validation via API
 */
class Lixvalid
{
    /**
     * License API endpoints
     */
    private const API_VALIDATE = 'http://api.matheme.app/api/license/validate';

    private const API_INDEPENDENCE_STATUS = 'http://api.matheme.app/api/license/independence-status';

    /**
     * Request timeout in seconds
     */
    private const TIMEOUT = 30;

    public function __construct(
        private LixServ $lixServ
    ) {}

    /**
     * Validate license
     * Returns validation result with status and message
     */
    public function validate(): array
    {
        // Check if license exists
        if (! $this->lixServ->hasLicense()) {
            return [
                'valid' => false,
                'status' => 'missing',
                'message' => 'No license found. Please activate your license.',
                'can_use' => false,
            ];
        }

        // Check domain match
        if (! $this->lixServ->isDomainValid()) {
            return [
                'valid' => false,
                'status' => 'domain_mismatch',
                'message' => 'License domain does not match current installation domain.',
                'can_use' => false,
            ];
        }

        // Check cached status first
        $cachedStatus = $this->lixServ->getCachedStatus();
        if ($cachedStatus && isset($cachedStatus['valid'])) {
            // If cached status is valid and recent, return it
            if ($cachedStatus['valid'] === true) {
                return $cachedStatus;
            }
        }

        // Verify with API
        return $this->verifyWithApi();
    }

    /**
     * Verify license with API
     */
    private function verifyWithApi(): array
    {
        try {
            $licenseCode = $this->lixServ->getLicenseCode();
            $email = $this->lixServ->getLicenseEmail();
            $domain = $this->lixServ->getCurrentDomain();
            $productId = $this->lixServ->getProductId();

            if (! $licenseCode || ! $email) {
                return [
                    'valid' => false,
                    'status' => 'invalid',
                    'message' => 'License information is incomplete.',
                    'can_use' => false,
                ];
            }

            $response = Http::timeout(self::TIMEOUT)->post(self::API_VALIDATE, [
                'license_code' => $licenseCode,
                'email' => $email,
                'domain' => $domain,
                'product' => $productId,
            ]);

            if ($response->successful()) {
                $data = $response->json();

                $result = [
                    'valid' => isset($data['valid']) && $data['valid'] === true,
                    'status' => $data['status'] ?? 'unknown',
                    'message' => $data['message'] ?? 'License check completed',
                    'can_use' => isset($data['can_use']) ? (bool) $data['can_use'] : false,
                    'expires_at' => $data['expires_at'] ?? null,
                    'verified_at' => now()->toDateTimeString(),
                ];

                // Cache the result
                $this->lixServ->cacheStatus($result);

                return $result;
            }

            // If API fails, use cached status if available (graceful degradation)
            $cachedStatus = $this->lixServ->getCachedStatus();
            if ($cachedStatus) {
                Log::warning('License API unavailable, using cached status');

                return array_merge($cachedStatus, [
                    'api_offline' => true,
                    'message' => 'License server unavailable. Using cached status.',
                ]);
            }

            return [
                'valid' => false,
                'status' => 'api_error',
                'message' => 'Unable to verify license. Please check your internet connection.',
                'can_use' => false,
            ];
        } catch (Exception $e) {
            Log::error('License validation error: '.$e->getMessage());

            // Graceful degradation - use cached status if available
            $cachedStatus = $this->lixServ->getCachedStatus();
            if ($cachedStatus) {
                return array_merge($cachedStatus, [
                    'api_error' => true,
                    'message' => 'License verification error. Using cached status.',
                ]);
            }

            return [
                'valid' => false,
                'status' => 'error',
                'message' => 'License verification failed. Please try again later.',
                'can_use' => false,
            ];
        }
    }

    /**
     * Quick check if license is valid (uses cache)
     */
    public function isValid(): bool
    {
        $status = $this->validate();

        return $status['valid'] === true && $status['can_use'] === true;
    }

    /**
     * Check if admin access is allowed
     */
    public function canAccessAdmin(): bool
    {
        $status = $this->validate();

        return $status['valid'] === true && $status['can_use'] === true;
    }

    /**
     * Check if frontend access is allowed (read-only)
     */
    public function canAccessFrontend(): bool
    {
        // Frontend is always accessible (read-only)
        // Only admin is restricted
        return true;
    }

    /**
     * Get license status details
     */
    public function getStatus(): array
    {
        return $this->validate();
    }

    /**
     * Check independence status
     * Use the independence status endpoint to check progress
     */
    public function getIndependenceStatus(): array
    {
        try {
            $licenseCode = $this->lixServ->getLicenseCode();
            $email = $this->lixServ->getLicenseEmail();
            $domain = $this->lixServ->getCurrentDomain();
            $productId = $this->lixServ->getProductId();

            if (! $licenseCode || ! $email) {
                return [
                    'success' => false,
                    'message' => 'License information is incomplete.',
                ];
            }

            $response = Http::timeout(self::TIMEOUT)->post(self::API_INDEPENDENCE_STATUS, [
                'license_code' => $licenseCode,
                'email' => $email,
                'domain' => $domain,
                'product' => $productId,
            ]);

            if ($response->successful()) {
                $data = $response->json();

                return [
                    'success' => true,
                    'data' => $data,
                    'independence_status' => $data['independence_status'] ?? 'unknown',
                    'progress' => $data['progress'] ?? null,
                    'message' => $data['message'] ?? 'Independence status retrieved',
                ];
            }

            return [
                'success' => false,
                'message' => 'Unable to retrieve independence status.',
            ];
        } catch (Exception $e) {
            Log::error('Independence status check error: '.$e->getMessage());

            return [
                'success' => false,
                'message' => 'Independence status check failed: '.$e->getMessage(),
            ];
        }
    }
}
