<?php

namespace App\Http\Controllers\Api;

use App\Http\Controllers\Controller;
use App\Models\License;
use App\Models\Product;
use App\Models\LicenseLog;
use App\Services\EnvatoService;
use Illuminate\Http\Request;
use Illuminate\Http\JsonResponse;

class LicenseController extends Controller
{
    protected $envatoService;

    public function __construct(EnvatoService $envatoService)
    {
        $this->envatoService = $envatoService;
    }

    /**
     * Verify license - checks local database first, then Envato as fallback
     */
    public function verify(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'purchase_code' => ['required', 'string'],
            'product_slug' => ['required', 'string'],
            'domain' => ['required', 'string'],
        ]);

        $purchaseCode = $validated['purchase_code'];
        $productSlug = $validated['product_slug'];
        $domain = parse_url($validated['domain'], PHP_URL_HOST) ?: $validated['domain'];

        // Check rate limiting
        if ($this->isRateLimited($purchaseCode, $request->ip())) {
            $response = [
                'valid' => false,
                'reason' => 'rate_limited',
                'message' => 'Too many verification attempts. Please try again later.'
            ];

            $this->logLicenseVerification(null, $domain, $request, $response, 'rate_limited');
            return response()->json($response, 429);
        }

        // First, try to find license in local database
        $localLicense = $this->checkLocalLicense($purchaseCode, $productSlug, $domain);

        if ($localLicense) {
            $response = [
                'valid' => true,
                'source' => 'local',
                'license_type' => 'system_generated',
                'purchase_code' => $localLicense->purchase_code,
                'product' => $localLicense->product->only(['id', 'name', 'slug', 'envato_item_id']),
                'domain_allowed' => $localLicense->domain_allowed,
                'status' => $localLicense->status,
                'support_expires_at' => optional($localLicense->support_expires_at)->toDateString(),
                'license_expires_at' => optional($localLicense->license_expires_at)->toDateString(),
            ];

            $this->logLicenseVerification($localLicense->license, $domain, $request, $response, 'success');
            return response()->json($response);
        }

        // If not found locally, check Envato
        $envatoResult = $this->checkEnvatoLicense($purchaseCode, $productSlug, $domain);

        if ($envatoResult['valid']) {
            $response = [
                'valid' => true,
                'source' => 'envato',
                'license_type' => 'envato_market',
                'purchase_code' => $purchaseCode,
                'product' => $envatoResult['product'],
                'domain_allowed' => $envatoResult['domain_allowed'],
                'status' => 'active',
                'support_expires_at' => $envatoResult['support_expires_at'],
                'license_expires_at' => $envatoResult['license_expires_at'],
            ];

            $this->logLicenseVerification(null, $domain, $request, $response, 'success');
            return response()->json($response);
        }

        // License not found in either source
        $response = [
            'valid' => false,
            'reason' => 'license_not_found',
            'message' => 'License not found in local database or Envato Market'
        ];

        $this->logLicenseVerification(null, $domain, $request, $response, 'failed');
        return response()->json($response, 404);
    }

    /**
     * Check license in local database
     */
    private function checkLocalLicense(string $purchaseCode, string $productSlug, string $domain): ?object
    {
        $license = License::with(['product', 'domains'])
            ->where('purchase_code', $purchaseCode)
            ->whereHas('product', fn($q) => $q->where('slug', $productSlug))
            ->where('status', 'active')
            ->first();

        if (!$license) {
            return null;
        }

        $domainAllowed = $license->domains()->where('domain', $domain)->exists();

        return (object) [
            'license' => $license,
            'domain_allowed' => $domainAllowed,
            'purchase_code' => $license->purchase_code,
            'product' => $license->product,
            'status' => $license->status,
            'support_expires_at' => $license->support_expires_at,
            'license_expires_at' => $license->license_expires_at,
        ];
    }

    /**
     * Check license with Envato API
     */
    private function checkEnvatoLicense(string $purchaseCode, string $productSlug, string $domain): array
    {
        try {
            // Find product by slug to get envato_item_id
            $product = Product::where('slug', $productSlug)->first();

            if (!$product || !$product->envato_item_id) {
                return ['valid' => false];
            }

            // Verify with Envato
            $envatoData = $this->envatoService->verifyPurchase($purchaseCode);

            if (!$envatoData) {
                return ['valid' => false];
            }

            // Check if the purchase belongs to the correct product
            $envatoItemId = (string) data_get($envatoData, 'item.id');
            if ($product->envato_item_id && $product->envato_item_id !== $envatoItemId) {
                return ['valid' => false];
            }

            // For Envato licenses, domain is always allowed (no domain restrictions)
            return [
                'valid' => true,
                'product' => $product->only(['id', 'name', 'slug', 'envato_item_id']),
                'domain_allowed' => true, // Envato licenses don't restrict domains
                'support_expires_at' => $envatoData['supported_until'] ?? null,
                'license_expires_at' => null, // Envato licenses don't expire
            ];

        } catch (\Exception $e) {
            // Log error but don't expose it
            // Envato license verification failed
            return ['valid' => false];
        }
    }

    /**
     * Check if license verification is rate limited
     */
    private function isRateLimited(string $purchaseCode, string $ipAddress): bool
    {
        $maxAttempts = \App\Models\Setting::get('license_max_attempts', 5);
        $lockoutMinutes = \App\Models\Setting::get('license_lockout_minutes', 15);

        $recentAttempts = LicenseLog::where('serial', $purchaseCode)
            ->where('ip_address', $ipAddress)
            ->where('created_at', '>=', now()->subMinutes($lockoutMinutes))
            ->count();

        return $recentAttempts >= $maxAttempts;
    }

    /**
     * Log license verification attempt
     */
    private function logLicenseVerification(?License $license, string $domain, Request $request, array $response, string $status): void
    {
        // Whitelist request fields to avoid storing sensitive or unexpected data
        $allowed = $request->only(['purchase_code', 'product_slug', 'domain', 'verification_key']);
        // Mask sensitive fields
        if (isset($allowed['purchase_code']) && is_string($allowed['purchase_code'])) {
            $allowed['purchase_code'] = substr($allowed['purchase_code'], 0, 4) . str_repeat('*', max(0, strlen($allowed['purchase_code']) - 4));
        }

        LicenseLog::create([
            'license_id' => $license?->id,
            'domain' => $domain,
            'ip_address' => $request->ip(),
            'serial' => $request->input('purchase_code'),
            'status' => $status,
            'user_agent' => $request->userAgent(),
            'request_data' => $allowed,
            'response_data' => $response,
        ]);
    }

    /**
     * Generate integration file for a product
     */
    public function generateIntegrationFile(Request $request): JsonResponse
    {
        $validated = $request->validate([
            'product_slug' => ['required', 'string'],
        ]);

        $product = Product::where('slug', $validated['product_slug'])->first();

        if (!$product) {
            return response()->json(['error' => 'Product not found'], 404);
        }

        $integrationCode = $this->generateIntegrationCode($product);

        return response()->json([
            'product' => $product->only(['name', 'slug']),
            'integration_file' => $integrationCode,
            'filename' => 'license_integration_' . $product->slug . '.php'
        ]);
    }

    /**
     * Generate PHP integration code for a product
     */
    private function generateIntegrationCode(Product $product): string
    {
    $apiDomain = rtrim(env('APP_URL', config('app.url')), '/');
    $verificationEndpoint = config('license.verification_endpoint', '/api/license/verify');
    $apiUrl = $apiDomain . '/' . ltrim($verificationEndpoint, '/');

        return "<?php

/**
 * License Integration for {$product->name}
 * Generated on " . now()->format('Y-m-d H:i:s') . "
 *
 * This file provides license verification functionality for {$product->name}
 * It supports both local system licenses and Envato Market licenses
 */

class LicenseManager
{
    private \$api_url = '{$apiUrl}';
    private \$product_slug = '{$product->slug}';
    private \$timeout = 30; // seconds

    /**
     * Verify license
     *
     * @param string \$license_key Purchase code or license key
     * @param string \$domain Domain to verify against
     * @return array Verification result
     */
    public function verifyLicense(\$license_key, \$domain = null)
    {
        if (empty(\$license_key)) {
            return [
                'valid' => false,
                'error' => 'License key is required'
            ];
        }

        // Use current domain if not provided
        if (\$domain === null) {
            \$domain = \$this->getCurrentDomain();
        }

        \$postData = [
            'purchase_code' => \$license_key,
            'product_slug' => \$this->product_slug,
            'domain' => \$domain
        ];

        \$response = \$this->makeApiCall(\$this->api_url, \$postData);

        if (\$response === false) {
            return [
                'valid' => false,
                'error' => 'Unable to verify license. Please check your internet connection.'
            ];
        }

        \$data = json_decode(\$response, true);

        if (json_last_error() !== JSON_ERROR_NONE) {
            return [
                'valid' => false,
                'error' => 'Invalid response from license server'
            ];
        }

        if (!isset(\$data['valid'])) {
            return [
                'valid' => false,
                'error' => 'Invalid response format'
            ];
        }

        return \$data;
    }

    /**
     * Get current domain
     */
    private function getCurrentDomain()
    {
        if (isset(\$_SERVER['HTTP_HOST'])) {
            return \$_SERVER['HTTP_HOST'];
        }

        if (isset(\$_SERVER['SERVER_NAME'])) {
            return \$_SERVER['SERVER_NAME'];
        }

        return 'localhost';
    }

    /**
     * Make API call to license server
     */
    private function makeApiCall(\$url, \$data)
    {
        \$ch = curl_init();

        curl_setopt(\$ch, CURLOPT_URL, \$url);
        curl_setopt(\$ch, CURLOPT_POST, true);
        curl_setopt(\$ch, CURLOPT_POSTFIELDS, http_build_query(\$data));
        curl_setopt(\$ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt(\$ch, CURLOPT_TIMEOUT, \$this->timeout);
        curl_setopt(\$ch, CURLOPT_SSL_VERIFYPEER, true);
        curl_setopt(\$ch, CURLOPT_USERAGENT, 'LicenseManager/1.0 ({$product->name})');

        \$response = curl_exec(\$ch);
        \$error = curl_error(\$ch);

        curl_close(\$ch);

        if (\$error) {
            return false;
        }

        return \$response;
    }

    /**
     * Check if license is valid and get details
     */
    public function getLicenseInfo(\$license_key, \$domain = null)
    {
        \$result = \$this->verifyLicense(\$license_key, \$domain);

        if (!\$result['valid']) {
            return false;
        }

        return [
            'license_key' => \$license_key,
            'product' => \$result['product'] ?? null,
            'source' => \$result['source'] ?? 'unknown',
            'license_type' => \$result['license_type'] ?? 'unknown',
            'status' => \$result['status'] ?? 'unknown',
            'domain_allowed' => \$result['domain_allowed'] ?? false,
            'support_expires_at' => \$result['support_expires_at'] ?? null,
            'license_expires_at' => \$result['license_expires_at'] ?? null,
        ];
    }
}

// Usage example:
/*
\$licenseManager = new LicenseManager();
\$result = \$licenseManager->verifyLicense('YOUR_LICENSE_KEY');

if (\$result['valid']) {
    echo 'License is valid!';
    echo 'Source: ' . \$result['source'];
    echo 'Type: ' . \$result['license_type'];
} else {
    echo 'License is invalid: ' . (\$result['error'] ?? 'Unknown error');
}
*/
";
    }
}