<?php

class LicenseService {
    private static $remote_api_url = null;

    private static function getApiUrl() {
        if (self::$remote_api_url === null) {
            self::$remote_api_url = getenv('LICENSE_API_URL') ?: 'https://omanapp.cloud/meezan_register/';
        }
        return self::$remote_api_url;
    }

    /**
     * Returns the number of days remaining in the trial.
     */
    public static function getTrialRemainingDays() {
        require_once __DIR__ . '/../db/config.php';
        self::ensureTrialSchema();
        $stmt = db()->prepare("SELECT trial_started_at FROM system_license LIMIT 1");
        $stmt->execute();
        $res = $stmt->fetch();

        if (!$res || !$res['trial_started_at']) {
            // self::startTrial(); // Disabled automatic trial start as per user request to keep things manual
            return 0; // Return 0 if trial not started
        }

        $started = strtotime($res['trial_started_at']);
        $days_elapsed = floor((time() - $started) / (24 * 60 * 60));
        
        return (int) max(0, 15 - $days_elapsed);
    }

    /**
     * Ensures the database schema for the trial period exists.
     */
    private static function ensureTrialSchema() {
        require_once __DIR__ . '/../db/config.php';
        try {
            $db = db();
            // Check if table exists
            $tableExists = $db->query("SHOW TABLES LIKE 'system_license'")->fetch();
            
            if (!$tableExists) {
                $db->exec("CREATE TABLE system_license (
                    id INT AUTO_INCREMENT PRIMARY KEY,
                    license_key VARCHAR(255) DEFAULT '',
                    activation_token TEXT DEFAULT NULL,
                    fingerprint VARCHAR(255) DEFAULT NULL,
                    status ENUM('pending', 'active', 'expired', 'suspended', 'trial') DEFAULT 'pending',
                    allowed_activations INT DEFAULT 1,
                    activated_at DATETIME DEFAULT NULL,
                    last_checked_at DATETIME DEFAULT NULL,
                    trial_started_at DATETIME DEFAULT NULL,
                    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
                )");
            } else {
                // Check if trial_started_at column exists
                $stmt = $db->query("SHOW COLUMNS FROM system_license LIKE 'trial_started_at'");
                if (!$stmt->fetch()) {
                    $db->exec("ALTER TABLE system_license ADD COLUMN trial_started_at DATETIME DEFAULT NULL");
                }

                // Check if allowed_activations column exists
                $stmt = $db->query("SHOW COLUMNS FROM system_license LIKE 'allowed_activations'");
                if (!$stmt->fetch()) {
                    $db->exec("ALTER TABLE system_license ADD COLUMN allowed_activations INT DEFAULT 1");
                }

                // Ensure 'trial' status exists in ENUM
                $stmt = $db->query("SHOW COLUMNS FROM system_license LIKE 'status'");
                $statusCol = $stmt->fetch();
                if ($statusCol && strpos($statusCol['Type'], "'trial'") === false) {
                    $db->exec("ALTER TABLE system_license MODIFY COLUMN status ENUM('pending', 'active', 'expired', 'suspended', 'trial') DEFAULT 'pending'");
                }
            }
        } catch (Exception $e) {
            // Log or ignore
        }
    }

    /**
     * Public wrapper to initialize the trial period.
     */
    public static function initTrial() {
        try {
            self::startTrial();
            return ['success' => true];
        } catch (Exception $e) {
            return ['success' => false, 'error' => $e->getMessage()];
        }
    }

    /**
     * Initializes the trial period.
     */
    private static function startTrial() {
        require_once __DIR__ . '/../db/config.php';
        self::ensureTrialSchema();
        $stmt = db()->prepare("SELECT COUNT(*) FROM system_license");
        $stmt->execute();
        if ($stmt->fetchColumn() == 0) {
            db()->exec("INSERT INTO system_license (license_key, status, trial_started_at) VALUES ('TRIAL', 'trial', NOW())");
        } else {
            db()->exec("UPDATE system_license SET trial_started_at = NOW() WHERE trial_started_at IS NULL");
        }
    }

    /**
     * Generates a unique fingerprint for this server environment.
     */
    public static function getFingerprint() {
        $data = [
            php_uname('n'), // Nodename (hostname)
            php_uname('m'), // Machine type
            PHP_OS
        ];
        return hash('sha256', implode('|', $data));
    }

    /**
     * Returns the number of allowed activations/counters.
     */
    public static function getAllowedActivations() {
        require_once __DIR__ . '/../db/config.php';
        $stmt = db()->prepare("SELECT allowed_activations FROM system_license WHERE status = 'active' ORDER BY id DESC LIMIT 1");
        $stmt->execute();
        $res = $stmt->fetch();
        
        if ($res) {
            return (int)$res['allowed_activations'];
        }
        
        // If in trial, allow maybe 1 or 2? Let's say 1 for now or based on user's preference.
        // But the user said "same as number of activations".
        return 1;
    }

    /**
     * Checks if the system is currently activated or within trial period.
     */
    public static function canAccess() {
        if (self::isActivated()) return true;

        $daysLeft = self::getTrialRemainingDays();
        return $daysLeft > 0;
    }

    /**
     * Checks if the system is currently activated with a valid license key.
     */
    public static function isActivated() {
        require_once __DIR__ . '/../db/config.php';
        $fingerprint = self::getFingerprint();
        $stmt = db()->prepare("SELECT * FROM system_license WHERE status = 'active' AND fingerprint = ? LIMIT 1");
        $stmt->execute([$fingerprint]);
        $license = $stmt->fetch();

        if (!$license) return false;

        // 1. Verify fingerprint matches (Physical Protection)
        if ($license['fingerprint'] !== $fingerprint) {
            return false;
        }

        // 2. Periodic Remote Validation (e.g., every 7 days)
        // This ensures if you disable a key on your server, the client will stop working.
        $last_check = strtotime($license['activated_at']); // In real use, store 'last_verified_at'
        if (time() - $last_check > (7 * 24 * 60 * 60)) {
            // It's been more than 7 days, let's re-verify
            $res = self::callRemoteApi('/verify', [
                'license_key' => $license['license_key'],
                'fingerprint' => $license['fingerprint'],
                'token' => $license['activation_token']
            ]);
            
            if (!$res['success']) {
                db()->prepare("UPDATE system_license SET status = 'suspended' WHERE fingerprint = ?")->execute([$fingerprint]);
                return false;
            }
            
            // Update last verified timestamp
            db()->prepare("UPDATE system_license SET activated_at = NOW() WHERE fingerprint = ?")->execute([$fingerprint]);
        }

        return true;
    }

    /**
     * Attempts to activate the product online.
     */
    public static function activate($license_key) {
        $license_key = trim($license_key);
        $fingerprint = self::getFingerprint();
        
        // Call remote API for real validation
        $response = self::callRemoteApi('/activate', [
            'license_key' => $license_key,
            'fingerprint' => $fingerprint,
            'domain' => $_SERVER['HTTP_HOST'] ?? 'unknown',
            'product' => 'Flatlogic Admin Panel'
        ]);

        if (!$response['success']) {
            return ['success' => false, 'error' => $response['error'] ?? 'Remote activation failed.'];
        }

        require_once __DIR__ . '/../db/config.php';
        
        // Clear previous entries for THIS fingerprint to avoid duplicates
        $stmt = db()->prepare("DELETE FROM system_license WHERE fingerprint = ?");
        $stmt->execute([$fingerprint]);

        // Check if we reached the limit of activations for this key (in a shared DB)
        $allowed = (int) ($response['allowed_activations'] ?? 1);
        $stmt = db()->prepare("SELECT COUNT(DISTINCT fingerprint) FROM system_license WHERE license_key = ? AND status = 'active'");
        $stmt->execute([$license_key]);
        $current_activations = (int) $stmt->fetchColumn();

        if ($current_activations >= $allowed) {
            return [
                'success' => false, 
                'error' => "Activation Limit Reached: This license only allows $allowed machine(s). Please deactivate another machine first."
            ];
        }

        $stmt = db()->prepare("INSERT INTO system_license (license_key, fingerprint, status, activated_at, activation_token, allowed_activations) VALUES (?, ?, 'active', NOW(), ?, ?)");
        $token = $response['activation_token'] ?? bin2hex(random_bytes(32)); 
        $stmt->execute([$license_key, $fingerprint, $token, $allowed]);

        return ['success' => true];
    }

    /**
     * Fetches all licenses from the remote server.
     */
    public static function listLicenses() {
        return self::callRemoteApi('/list', []);
    }

    /**
     * Updates an existing license.
     */
    public static function updateLicense($id, $data) {
        $params = array_merge(['id' => $id, 'secret' => '1485-5215-2578'], $data);
        return self::callRemoteApi('/update', $params);
    }

    /**
     * Issues a new license.
     */
    public static function issueLicense($max_activations, $prefix = 'FLAT', $owner = null, $address = null) {
        return self::callRemoteApi('/issue', [
            'secret' => '1485-5215-2578',
            'max_activations' => $max_activations,
            'prefix' => $prefix,
            'owner' => $owner,
            'address' => $address
        ]);
    }

    /**
     * Remote API Caller
     */
    private static function callRemoteApi($endpoint, $params) {
        $action = ltrim($endpoint, '/');
        $url = rtrim(self::getApiUrl(), '/') . '/index.php?action=' . $action;
        
        // Check if we are in local development / simulation mode
        if (strpos($url, 'your-domain.com') !== false) {
            return self::simulateApi($endpoint, $params);
        }

        $ch = curl_init($url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($params));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_TIMEOUT, 10);
        $resp = curl_exec($ch);
        $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);

        if ($http_code !== 200) {
            return ['success' => false, 'error' => "Remote server returned error code $http_code."];
        }

        $data = json_decode($resp, true);
        if (!$data) {
            return ['success' => false, 'error' => "Invalid response from remote server."];
        }

        return $data;
    }

    /**
     * Local Simulation for development purposes
     */
    private static function simulateApi($endpoint, $params) {
        $clean_key = strtoupper(trim($params['license_key'] ?? ''));
        
        // Strict format check: FLAT-XXXX-XXXX-XXXX (where X is hex)
        $pattern = '/^FLAT-[0-9A-F]{4}-[0-9A-F]{4}-[0-9A-F]{4}$/';
        
        if (!preg_match($pattern, $clean_key)) {
            return [
                'success' => false, 
                'error' => 'Invalid License Format. Expected FLAT-XXXX-XXXX-XXXX (Simulation Mode).'
            ];
        }

        // In a real server, you would check if this key is already used by a DIFFERENT fingerprint.
        // To simulate a "Max Activations Reached" error, you can use a specific key:
        if ($clean_key === 'FLAT-0000-0000-0000') {
            return [
                'success' => false,
                'error' => 'Activation Failed: This license key is already active on another machine.'
            ];
        }

        if ($endpoint === '/verify') return ['success' => true];
        
        return [
            'success' => true,
            'allowed_activations' => 2, // Simulate a license that allows 2 machines/counters
            'activation_token' => hash('sha256', $params['license_key'] . $params['fingerprint'] . 'DEBUG_SALT')
        ];
    }
}
