<?php

namespace App\Installer\Services;

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

/**
 * License Verifier Service
 * Handles license verification with external API
 */
class LicenseVerifier
{
    /**
     * License API endpoint for installation verification
     *
     * DEVELOPMENT: Local development endpoint
     * Backend API runs on port 8000 (frontend is on port 3000)
     * Endpoint: POST /api/license/verify-installation
     * Required parameters: license_key, domain
     * Response: { can_install: boolean, message: string }
     */
    private const LICENSE_API_URL_DEV = 'http://localhost:8000/api/license/verify-installation';

    /**
     * PRODUCTION: Production endpoint (commented out for development)
     * Uncomment and use this when deploying to production
     */
    // private const LICENSE_API_URL_PROD = 'https://api.matheme.dev/api/license/verify-installation';

    /**
     * Current API URL (set to development for now)
     * TO CHANGE FOR PRODUCTION: Edit this file and switch to LICENSE_API_URL_PROD
     */
    private const LICENSE_API_URL = self::LICENSE_API_URL_DEV;

    public function __construct(
        private LicenseStorage $licenseStorage
    ) {}

    /**
     * Verify license with external API
     */
    public function verify(string $licenseCode, string $email, string $domain): array
    {
        try {
            // First, test if the API server is reachable (backend on port 8000)
            try {
                $testResponse = Http::timeout(5)->get('http://localhost:8000');
                \Log::info('API server connectivity test', [
                    'reachable' => $testResponse->successful(),
                    'status' => $testResponse->status(),
                ]);
            } catch (\Exception $e) {
                \Log::warning('API server may not be running on port 8000', [
                    'error' => $e->getMessage(),
                ]);
            }

            // API expects: license_key and domain (according to API documentation)
            $payload = [
                'license_key' => $licenseCode, // API expects 'license_key' not 'license_code'
                'domain' => $domain,
            ];

            \Log::info('License verification request', [
                'url' => self::LICENSE_API_URL,
                'payload' => $payload,
            ]);

            // Make request with proper JSON headers
            // Try JSON first (most APIs expect this)
            $response = Http::timeout(30)
                ->acceptJson()
                ->asJson()
                ->withHeaders([
                    'Content-Type' => 'application/json',
                    'Accept' => 'application/json',
                ])
                ->post(self::LICENSE_API_URL, $payload);

            $statusCode = $response->status();
            $responseBody = $response->body();
            $responseData = $response->json();

            \Log::info('License verification response', [
                'status' => $statusCode,
                'body' => $responseBody,
                'json' => $responseData,
            ]);

            if ($response->successful()) {
                $data = $responseData ?? [];

                // API returns can_install field according to documentation
                // Check if installation is allowed
                $canInstall = false;
                if (isset($data['can_install']) && $data['can_install'] === true) {
                    $canInstall = true;
                } elseif (isset($data['valid']) && $data['valid'] === true) {
                    $canInstall = true; // Fallback for other response formats
                } elseif (isset($data['success']) && $data['success'] === true) {
                    $canInstall = true; // Fallback for other response formats
                }

                if ($canInstall) {
                    // Store license info securely
                    $this->storeLicenseInfo($licenseCode, $email, $domain, $data);

                    return [
                        'success' => true,
                        'message' => $data['message'] ?? 'License verified successfully. Installation can proceed.',
                        'data' => $data,
                    ];
                }

                // Installation not allowed - show error message from API
                $errorMessage = $data['message'] ?? $data['error'] ?? 'License verification failed. Installation is not allowed for this license key and domain.';

                return [
                    'success' => false,
                    'message' => $errorMessage,
                ];
            }

            // Handle HTTP errors with more detail
            $errorMessage = 'Unable to connect to license server (HTTP '.$statusCode.')';

            if ($responseData && isset($responseData['message'])) {
                $errorMessage = $responseData['message'];
            } elseif ($responseData && isset($responseData['error'])) {
                $errorMessage = $responseData['error'];
            } elseif ($responseBody) {
                $errorMessage .= '. Response: '.substr($responseBody, 0, 200);
            }

            // For 404, provide helpful message with troubleshooting
            if ($statusCode === 404) {
                $errorMessage = 'License API endpoint not found (404). The endpoint `/api/license/verify-installation` does not exist on your API server.';

                // Try to discover the correct endpoint (on port 8000 - backend API)
                $alternativeEndpoints = [
                    'http://localhost:8000/api/license/verify',
                    'http://localhost:8000/api/license/validate',
                    'http://localhost:8000/api/license/install',
                    'http://localhost:8000/api/license/check',
                ];

                $foundEndpoints = [];
                foreach ($alternativeEndpoints as $altUrl) {
                    try {
                        $altResponse = Http::timeout(3)->post($altUrl, $payload);
                        $altStatus = $altResponse->status();
                        \Log::info('Testing alternative endpoint', [
                            'url' => $altUrl,
                            'status' => $altStatus,
                        ]);

                        if ($altStatus !== 404) {
                            $foundEndpoints[] = $altUrl.' (HTTP '.$altStatus.')';
                        }
                    } catch (\Exception $e) {
                        // Ignore alternative endpoint errors
                    }
                }

                if (! empty($foundEndpoints)) {
                    $errorMessage .= ' Found these endpoints that responded (not 404): '.implode(', ', $foundEndpoints);
                } else {
                    $errorMessage .= ' Please check your API server routes and verify the endpoint path.';
                }

                $errorMessage .= ' Current endpoint: '.self::LICENSE_API_URL;
            }

            return [
                'success' => false,
                'message' => $errorMessage,
            ];
        } catch (\Illuminate\Http\Client\ConnectionException $e) {
            \Log::error('License verification connection error', [
                'message' => $e->getMessage(),
                'url' => self::LICENSE_API_URL,
            ]);

            return [
                'success' => false,
                'message' => 'Cannot connect to license server. Please ensure the backend API server is running on port 8000 at '.self::LICENSE_API_URL,
            ];
        } catch (Exception $e) {
            \Log::error('License verification exception', [
                'message' => $e->getMessage(),
                'trace' => $e->getTraceAsString(),
            ]);

            return [
                'success' => false,
                'message' => 'License verification error: '.$e->getMessage(),
            ];
        }
    }

    /**
     * Store license information securely
     */
    private function storeLicenseInfo(string $licenseCode, string $email, string $domain, array $data): void
    {
        $licenseData = [
            'license_code' => encrypt($licenseCode),
            'email' => encrypt($email),
            'domain' => $domain,
            'verified_at' => now(),
            'license_data' => encrypt(json_encode($data)),
        ];

        $this->licenseStorage->store($licenseData);
    }
}
