<?php
defined('ABSPATH') || exit;

if (!class_exists('AI_APP_ONSITE_App_License_Handler')) {
    class AI_APP_ONSITE_App_License_Handler
    {
        private $table_name;
        const HOOK = 'ai_app_onsite_check_license_cron';

        public function __construct()
        {
            global $wpdb;
            $this->table_name = $wpdb->prefix . 'ai_app_onsite_license_settings';

            add_action('wp_ajax_ai_app_onsite_app_verify_license_key', [$this, 'ai_app_onsite_app_verify_license_key_callback']);
            add_action('wp_ajax_nopriv_ai_app_onsite_app_verify_license_key', [$this, 'ai_app_onsite_app_verify_license_key_callback']);

            add_action('wp_ajax_ai_app_onsite_get_app_license_key', [$this, 'ai_app_onsite_get_app_get_license_key_callback']);
            add_action('wp_ajax_nopriv_ai_app_onsite_get_app_license_key', [$this, 'ai_app_onsite_get_app_get_license_key_callback']);

            add_action('wp_ajax_ai_app_onsite_app_remove_license_key', [$this, 'ai_app_onsite_app_remove_license_key_callback']);
            add_action('wp_ajax_nopriv_ai_app_onsite_app_remove_license_key', [$this, 'ai_app_onsite_app_remove_license_key_callback']);

            add_action('wp_ajax_ai_app_onsite_app_toggle_license_key_status', [$this, 'ai_app_onsite_app_toggle_license_key_status_callback']);
            add_action('wp_ajax_nopriv_ai_app_onsite_app_toggle_license_key_status', [$this, 'ai_app_onsite_app_toggle_license_key_status_callback']);

            add_action(self::HOOK, [$this, 'ai_app_onsite_app_check_license_cron_callback']);

            if (!wp_next_scheduled(self::HOOK)) {
                wp_clear_scheduled_hook('ai_app_onsite_check_license_cron');
                wp_schedule_event(time(), 'validatelicense', self::HOOK);
            }
        }

        private function is_request_authorized($nonce_field_name, $nonce_action)
        {
            return is_user_logged_in() &&
                   isset($_POST[$nonce_field_name]) &&
                   wp_verify_nonce(sanitize_text_field(wp_unslash($_POST[$nonce_field_name])), $nonce_action);
        }

        public function ai_app_onsite_get_app_get_license_key_callback()
        {
            if (!is_user_logged_in()) {
                wp_send_json_error('Unauthorized');
            }

            global $wpdb;
            $results = $wpdb->get_results("SELECT * FROM {$this->table_name}", ARRAY_A);
            if (empty($results)) {
                wp_send_json([
                    'status' => '404',
                    'message' => 'No Access Key Found.'
                ]);
            }
            $results[0]['license_key_hd'] = $this->ai_app_onsite_decrypt_string($results[0]['license_key']);
            $results[0]['license_key'] = $this->ai_app_onsite_mask_license_key($results[0]['license_key']);
            wp_send_json($results);
        }

        private function ai_app_onsite_mask_license_key($key) {
            $key = $this->ai_app_onsite_decrypt_string($key);
            $key = trim($key);
            if (strlen($key) < 4) {
                return str_repeat('x', strlen($key));
            }
            return str_repeat('x', strlen($key) - 4) . substr($key, -4);
        }

        public function ai_app_onsite_app_remove_license_key_callback()
        {
            if (!is_user_logged_in()) {
                wp_send_json_error('Unauthorized');
            }

            global $wpdb;

            $license_row = $wpdb->get_row("SELECT * FROM {$this->table_name}", ARRAY_A);

            $wpdb->update(
                $this->table_name,
                [
                    'key_status' => 'INACTIVE',
                    'updated_at' => current_time('mysql'),
                ],
                ['id' => $license_row['id']],
                ['%s', '%s'],
                ['%d']
            );

            $this->ai_app_onsite_archive_app_extract();

            wp_send_json_success('Access key removed successfully.');
        }

        public function ai_app_onsite_app_toggle_license_key_status_callback()
        {
            if (!is_user_logged_in()) {
                wp_send_json_error('Unauthorized');
            }

            $license_key_disable_status = isset($_POST['status']) ? sanitize_text_field(wp_unslash($_POST['status'])) : '';
            
            if (empty($license_key_disable_status)) {
                wp_send_json_error('Access key action cannot be empty.');
            }

            global $wpdb;
           
            // Fetch the current key_disable_status
            $current_disable_status = $wpdb->get_row("SELECT key_disable_status, subscription_expiry_date FROM {$this->table_name} WHERE app_id = 1", ARRAY_A);
           
            if (!$current_disable_status) {
                wp_send_json_error('Access key not found.');
            }

            // Toggle the disable status
            $new_disable_status = ($license_key_disable_status != 'Enabled') ? 'true' : 'false';
         
            $subscription_expiry_date = $current_disable_status['subscription_expiry_date'] ?? null;
 
            // Update the database
            $wpdb->update(
                $this->table_name,
                [
                    'key_disable_status' => $new_disable_status,
                    'subscription_expiry_date' => $subscription_expiry_date,
                    'updated_at' => current_time('mysql')
                ],
                ['app_id' => 1],
                ['%s', '%s', '%s'],
                ['%d']
            );
            

            if ($wpdb->last_error) {
                wp_send_json_error('DB update failed: ' . $wpdb->last_error);
            }

            wp_send_json_success("Access key disable status updated to {$new_disable_status} successfully.");
            // Fetch the current key_status
            $current_status = $wpdb->get_var("SELECT key_status FROM {$this->table_name} WHERE app_id = 1");
            
            if (!$current_status) {
                wp_send_json_error('Access key not found.');
            }
        }

        public function ai_app_onsite_app_verify_license_key_callback()
        {
            if (!$this->is_request_authorized('ai_app_onsite_app_verify_license_key_nonce_field', 'ai_app_onsite_app_verify_license_key_nonce')) {
                wp_send_json_error('Unauthorized request');
            }

            $license_key = isset($_POST['licence_key']) ? sanitize_text_field(wp_unslash($_POST['licence_key'])) : '';
            $status = isset($_POST['status']) ? sanitize_text_field(wp_unslash($_POST['status'])) : '';

            if (empty($license_key)) {
                wp_send_json_error('Access key cannot be empty.');
            }

            global $wpdb;

            $verify_response = $this->ai_app_onsite_send_to_external_api([
                'access_key' => $license_key,
                'domain' => $_SERVER['HTTP_HOST']
            ]);
           
            if (!$verify_response['success'] || $verify_response['data']['is_expired']) {
                wp_send_json_error($verify_response['message']);
            } 
                
            // Download and extract the premium ZIP (no version check here)
            $version_meta = ai_app_onsite_get_version_meta();
            if ( isset($version_meta['download_url']) ){ 
                $this->ai_app_onsite_app_extract($version_meta['download_url']);
            }

            $license_key_encrypted = $this->ai_app_onsite_encrypt_string($license_key);

            $data = [
                'license_key' => $license_key_encrypted,
                'key_status' => 'ACTIVE',
                'subscription_expiry_date' => $verify_response['data']['user_data']['expiry_date'],
                'key_disable_status' => $status,
                'updated_at' => current_time('mysql')
            ];

            $existing = $wpdb->get_row("SELECT * FROM {$this->table_name}");
            

            if ($existing) {
                $wpdb->update(
                    $this->table_name,
                    $data,
                    ['id' => $existing->id],
                    ['%s', '%s', '%s', '%s', '%s'],
                    ['%d']
                );

                if ($wpdb->last_error) {
                    wp_send_json_error('DB update failed: ' . $wpdb->last_error);
                }

                wp_send_json_success('Access key verified and updated successfully.');
            } else {
                $wpdb->insert(
                    $this->table_name,
                    [
                        'app_id'      => 1,
                        'license_key' => $license_key_encrypted,
                        'key_status'  => 'ACTIVE',
                        'subscription_expiry_date' => $verify_response['data']['user_data']['expiry_date'],
                        'key_disable_status' => 'false',
                        'created_at' => current_time('mysql'),
                        'updated_at' => current_time('mysql')
                    ],
                    ['%d', '%s', '%s', '%s', '%s', '%s', '%s']
                );

                if ($wpdb->last_error) {
                    wp_send_json_error('DB insert failed: ' . $wpdb->last_error);
                }

                wp_send_json_success('Access key verified and saved successfully.');
            }
        }

        public function ai_app_onsite_app_check_license_cron_callback()
        {
            error_log('[AI License Cron] Cron triggered at: ' . current_time('mysql'));

            global $wpdb;
            $license_row = $wpdb->get_row("SELECT * FROM {$this->table_name}", ARRAY_A);

            if (!$license_row || empty($license_row['license_key'])) {
                error_log('[AI License Cron] No valid license key found.');
                return;
            }

            $license_key =  $this->ai_app_onsite_decrypt_string($license_row['license_key']);

            $data = [
                'access_key' => $license_key,
                'domain' =>  $_SERVER['HTTP_HOST']
            ];

            //Check validity of the access key
            $response = $this->ai_app_onsite_send_to_external_api($data);

            if ($response['success'] && !$response['data']['is_expired']) {
                $wpdb->update(
                    $this->table_name,
                    [
                        'key_status' => 'ACTIVE',
                        'subscription_expiry_date' => $response['data']['user_data']['expiry_date'],
                        'updated_at' => current_time('mysql'),
                    ],
                    ['id' => $license_row['id']],
                    ['%s', '%s', '%s'],
                    ['%d']
                );
                $version_meta = ai_app_onsite_get_version_meta();

                if ( isset($version_meta['download_url']) ) {
                    $this->ai_app_onsite_app_extract($version_meta['download_url']);
                }
            } else {
                // remove 
                $wpdb->update(
                    $this->table_name,
                    [
                        'key_status' => 'INACTIVE',
                        'updated_at' => current_time('mysql'),
                    ],
                    ['id' => $license_row['id']],
                    ['%s', '%s'],
                    ['%d']
                );

                $this->ai_app_onsite_archive_app_extract();
            }
        }

        private function ai_app_onsite_send_to_external_api($data) {
            // Retrieve our license-server URL (stored Base64-encoded to avoid hard-coding)
            $api_url = base64_decode(get_option('ai_app_onsite_api_key'));

            if (!filter_var($api_url, FILTER_VALIDATE_URL)) {
                return [
                    'success' => false,
                    'message' => 'Invalid API endpoint'
                ];
            }

            $response = wp_remote_post($api_url, [
                'method'    => 'POST',
                'headers'   => ['Content-Type' => 'application/json'],
                'body'      => stripslashes(wp_json_encode($data)),
                'timeout'   => 20,
            ]);

            if (is_wp_error($response)) {
                return [
                    'success' => false,
                    'message' => 'API Error: ' . $response->get_error_message()
                ];
            }

            $decoded = json_decode(wp_remote_retrieve_body($response), true);
            if (isset($decoded['status_code']) && $decoded['status_code'] === 200) {
                return [
                    'success' => true,
                    'message' => 'License verified',
                    'data' => $decoded
                ];
            }else {
                return [
                    'success' => false,
                    'message' => $decoded['message'] ?? 'License invalid'
                ];
            }
        }

        /**
         * Encrypt a string using AES-256-CBC and return it Base64-encoded. Encrypt license key securely (not obfuscation).
         *
         * @param string $string The plaintext to encrypt.
         * @return string       The Base64-encoded ciphertext.
         */
        private function ai_app_onsite_encrypt_string($string) {
            return base64_encode(openssl_encrypt($string, 'AES-256-CBC', $this->ai_app_onsite_get_encryption_key(), 0, $this->ai_app_onsite_get_encryption_iv()));
        }
        
        /**
         * Decrypt a Base64-encoded AES-256-CBC ciphertext. Decrypting license key (not obfuscation)
         *
         * @param string $encrypted The Base64-encoded ciphertext.
         * @return string|false     The decrypted plaintext, or false on failure.
         */
        private function ai_app_onsite_decrypt_string($encrypted) {
            // First, decode from Base64 to get the raw ciphertext
            $decoded = base64_decode( $encrypted );

            // Retrieve the same key and IV used for encryption
            $key = $this->ai_app_onsite_get_encryption_key();
            $iv  = $this->ai_app_onsite_get_encryption_iv();

            // Decrypt and return the plaintext
            return openssl_decrypt(
                $decoded,
                'AES-256-CBC',
                $key,
                0,
                $iv
            );
        }

        /**
         * Retrieve the encryption key from the WordPress options table.
         *
         * @return string The raw encryption key.
         */
        private function ai_app_onsite_get_encryption_key() {
            // stored via aiapp_set_option('ai_app_onsite_encryption_key', $key)
            return get_option('ai_app_onsite_encryption_key');
        }

        /**
         * Retrieve or generate a 16-byte initialization vector (IV) for AES-256-CBC.
         *
         * @return string The raw 16-byte IV.
         */
        private function ai_app_onsite_get_encryption_iv() {
            // Attempt to fetch a Base64-encoded IV from the database
            $iv = get_option('ai_app_onsite_encryption_iv');
        
            if (!$iv) {
                // If none exists, generate a new random 16-byte IV
                $iv = base64_encode(random_bytes(16));
                aiapp_set_option('ai_app_onsite_encryption_iv', $iv);
            }
        
            // Decode from Base64 to get the raw IV for OpenSSL
            return base64_decode($iv);
        }
        
        private function ai_app_onsite_app_extract($zip_url) {
            if ($zip_url && filter_var($zip_url, FILTER_VALIDATE_URL)) {
                $plugin_root_dir = plugin_dir_path(__DIR__);
                $zip_file = $plugin_root_dir . 'premium_plugin.zip';

                // Download the zip file
                $response = wp_remote_get($zip_url, ['timeout' => 60]);
                if (!is_wp_error($response) && wp_remote_retrieve_response_code($response) === 200) {
                    file_put_contents($zip_file, wp_remote_retrieve_body($response));

                    // Extract the zip file
                    $zip = new ZipArchive();
                    if ($zip->open($zip_file) === true) {
                        $zip->extractTo($plugin_root_dir);
                        $zip->close();

                        // Clean up the zip file
                        unlink($zip_file);

                        $macosx_path = $plugin_root_dir . '__MACOSX';
                        if (is_dir($macosx_path)) {
                            $this->ai_app_onsite_rrmdir($macosx_path);
                        }

                    } else {
                        return [
                            'success' => false,
                            'message' => 'Failed to extract the premium plugin.'
                        ];
                    }
                } else {
                    return [
                        'success' => false,
                        'message' => 'Failed to download the premium plugin.'
                    ];
                }
            } else {
                return [
                    'success' => false,
                    'message' => 'Invalid or missing premium plugin URL.'
                ];
            }
        }
        

        private function ai_app_onsite_archive_app_extract() {
            $plugin_root_dir = plugin_dir_path(__DIR__);
            $premium_folder_path = $plugin_root_dir . 'premium/';
        
            if (is_dir($premium_folder_path)) {
                $this->ai_app_onsite_rrmdir($premium_folder_path);
            }
        }

        private function ai_app_onsite_rrmdir($dir) {
            foreach (scandir($dir) as $file) {
                if ($file !== '.' && $file !== '..') {
                    $path = $dir . DIRECTORY_SEPARATOR . $file;
                    is_dir($path) ? $this->ai_app_onsite_rrmdir($path) : unlink($path);
                }
            }
            return rmdir($dir);
        }

        public function ai_app_onsite_deactivate()
        {
            wp_clear_scheduled_hook(self::HOOK);
        }

    }

    $license_handler = new AI_APP_ONSITE_App_License_Handler();

    register_deactivation_hook(__FILE__, [$license_handler, 'ai_app_onsite_deactivate']);
}
