<?php
if (!defined('ABSPATH')) {
    exit;
}

class KDSAMREF_Pro_Codeon_Client {
    private $license_server;
    private $product_id;
    private $version;
    private $license_option = 'kdsamref_pro_license_key';
    private $cache_key = 'kdsamref_pro_license_status';

    public function __construct($product_id = 'orderable-kds-pro', $server_url = 'https://codeon.ch') {
        $this->version = defined('KDSAMREF_PRO_VERSION') ? KDSAMREF_PRO_VERSION : '3.0.1';

        // Prefer settings to determine server and product mapping
        // Embedded server selection: use local Codeon V2 if present, else codeon.ch
        $configured_server = class_exists('Codeon_License_Manager_V2') ? home_url('/') : $server_url;
        $this->license_server = trailingslashit(rtrim($configured_server, '/')) . 'wp-json/codeon-license/v2/';

        // Product ID: prefer numeric product id from settings for V2 compatibility
        // Embedded product id: prefer defined constant, fallback to constructor argument
        if (defined('KDSAMREF_PRO_PRODUCT_ID')) {
            $this->product_id = (string) intval(KDSAMREF_PRO_PRODUCT_ID);
        } else {
            $this->product_id = sanitize_text_field($product_id);
        }

        add_action('wp_loaded', array($this, 'schedule_hourly_check'));
        add_action('kdsamref_pro_hourly_license_check', array($this, 'hourly_license_check'));

        // Telemetry endpoints (AJAX optional)
        add_action('wp_ajax_kdsamref_pro_track_usage', array($this, 'ajax_track_usage'));

        // Track dashboard usage (admin screen) with throttling
        add_action('current_screen', array($this, 'maybe_track_dashboard'));
    }

    public function schedule_hourly_check() {
        if (!wp_next_scheduled('kdsamref_pro_hourly_license_check')) {
            wp_schedule_event(time(), 'hourly', 'kdsamref_pro_hourly_license_check');
        }
    }

    public function hourly_license_check() {
        $license_key = get_option($this->license_option);
        if (empty($license_key)) {
            return;
        }
        $this->clear_license_cache();
        $this->validate_license($license_key);
        if ($this->should_track()) {
            $this->track_usage('hourly_check');
        }
    }

    public function validate_license($license_key, $domain = null) {
        if (empty($license_key)) {
            return array('valid' => false, 'message' => __('License key is required', 'kds-report-for-orderable-pro'));
        }

        if (!$domain) {
            // Send full site URL to satisfy sanitize_url in API; server will normalize
            $domain = home_url();
        }

        $api_data = array(
            'license_key' => sanitize_text_field($license_key),
            'product_id'  => $this->product_id,
            'domain'      => sanitize_text_field($domain),
            'version'     => $this->version,
            'site_data'   => $this->collect_site_data(),
        );

        $response = wp_remote_post($this->license_server . 'validate', array(
            'headers' => array(
                'Content-Type' => 'application/json',
                'User-Agent'   => 'WRO-Pro/' . $this->version,
                'X-Site-Domain'=> $domain,
            ),
            'body'    => wp_json_encode($api_data),
            'timeout' => 20,
            'sslverify' => true,
        ));

        $result = $this->process_response($response, $license_key);
        // Persist latest status regardless of validity
        if (is_array($result)) {
            update_option('kdsamref_pro_license_status', $result);
            set_transient($this->cache_key, $result, 2 * MINUTE_IN_SECONDS);
        }
        if ($this->should_track()) {
            $this->track_usage('api_validate');
        }
        return $result;
    }

    public function activate_license($license_key, $domain = null) {
        if (empty($license_key)) {
            return array('success' => false, 'message' => __('License key is required', 'kds-report-for-orderable-pro'));
        }
        if (!$domain) {
            $domain = home_url();
        }

        $response = wp_remote_post($this->license_server . 'activate', array(
            'headers' => array('Content-Type' => 'application/json', 'User-Agent' => 'WRO-Pro/' . $this->version),
            'body'    => wp_json_encode(array(
                'license_key' => sanitize_text_field($license_key),
                'product_id'  => $this->product_id,
                'domain'      => sanitize_text_field($domain),
                'version'     => $this->version,
                'site_data'   => $this->collect_site_data(),
            )),
            'timeout' => 20,
            'sslverify' => true,
        ));
        return $this->process_response($response, $license_key);
    }

    public function deactivate_license($license_key, $domain = null) {
        if (!$domain) {
            $domain = home_url();
        }
        $response = wp_remote_post($this->license_server . 'deactivate', array(
            'headers' => array('Content-Type' => 'application/json', 'User-Agent' => 'WRO-Pro/' . $this->version),
            'body'    => wp_json_encode(array(
                'license_key' => sanitize_text_field($license_key),
                'product_id'  => $this->product_id,
                'domain'      => sanitize_text_field($domain),
            )),
            'timeout' => 15,
        ));
        $this->clear_license_cache();
        $result = $this->process_response($response, $license_key);
        // On deactivate endpoint, force inactive state locally and remove token
        $result['valid'] = false;
        $result['status'] = 'inactive';
        update_option('kdsamref_pro_license_status', $result);
        delete_option('kdsamref_pro_signed_token');
        // Also drop transient to avoid stale cached active state
        delete_transient($this->cache_key);
        return $result;
    }

    public function get_license_details($license_key) {
        if (empty($license_key)) {
            return null;
        }
        $cached = get_transient($this->cache_key);
        if ($cached) {
            return $cached;
        }
        // Prefer INFO endpoint for complete details; fallback to VALIDATE
        $info = $this->info_license($license_key);
        if (is_array($info) && (isset($info['valid']) ? $info['valid'] : true)) {
            set_transient($this->cache_key, $info, 2 * MINUTE_IN_SECONDS);
            return $info;
        }
        return $this->validate_license($license_key);
    }

    private function info_license($license_key) {
        $response = wp_remote_post($this->license_server . 'info', array(
            'headers' => array('Content-Type' => 'application/json', 'User-Agent' => 'WRO-Pro/' . $this->version),
            'body'    => wp_json_encode(array(
                'license_key' => sanitize_text_field($license_key)
            )),
            'timeout' => 15,
            'sslverify' => true,
        ));
        $result = $this->process_response($response, $license_key);
        if (is_array($result)) {
            update_option('kdsamref_pro_license_status', $result);
            set_transient($this->cache_key, $result, 2 * MINUTE_IN_SECONDS);
        }
        if ($this->should_track()) {
            $this->track_usage('api_info');
        }
        // Mark valid=true when info returns successfully without explicit valid flag
        if (is_array($result) && !isset($result['valid'])) {
            $result['valid'] = true;
        }
        return $result;
    }

    public function track_usage($action = 'admin_access') {
        $license_key = get_option($this->license_option);
        if (empty($license_key)) {
            return false;
        }
        $payload = array(
            'license_key' => $license_key,
            'product_id'  => $this->product_id,
            'action'      => sanitize_text_field($action),
            'domain'      => home_url(),
            'timestamp'   => current_time('mysql', true),
            'user_agent'  => $_SERVER['HTTP_USER_AGENT'] ?? '',
            'ip_address'  => $this->get_client_ip(),
        );
        wp_remote_post($this->license_server . 'track', array(
            'headers' => array('Content-Type' => 'application/json', 'User-Agent' => 'WRO-Pro/' . $this->version),
            'body'    => wp_json_encode($payload),
            'timeout' => 5,
            'blocking'=> false,
        ));
        return true;
    }

    public function ajax_track_usage() {
        if (!current_user_can('manage_options')) {
            wp_send_json_error(array('message' => 'forbidden'));
        }
        $action = isset($_POST['action_name']) ? sanitize_text_field($_POST['action_name']) : 'admin_access';
        if ($this->should_track()) {
            $this->track_usage($action);
        }
        wp_send_json_success();
    }

    private function should_track() {
        // Default to true (opt-in selected), allow admins to disable
        return (bool) get_option('kdsamref_pro_telemetry_opt_in', true);
    }

    public function maybe_track_dashboard($screen) {
        if (!is_object($screen)) { return; }
        // Only on our dashboard screens
        if (strpos($screen->id, 'kdsamref-') === false) { return; }
        if (!$this->should_track()) { return; }
        // Throttle to once per 15 minutes
        if (get_transient('kdsamref_pro_track_kds_dashboard')) { return; }
        set_transient('kdsamref_pro_track_kds_dashboard', 1, 15 * MINUTE_IN_SECONDS);
        $this->track_usage('kds_dashboard');
    }

    private function process_response($response, $license_key) {
        if (is_wp_error($response)) {
            return array('valid' => false, 'message' => $response->get_error_message(), 'license_key' => $license_key);
        }
        $code = (int) wp_remote_retrieve_response_code($response);
        $raw_body = wp_remote_retrieve_body($response);
        $body = json_decode($raw_body, true);

        if ($code >= 200 && $code < 300 && is_array($body)) {
            // Codeon License Manager V2 wraps responses as { success, data, message, ... }
            $has_envelope = array_key_exists('success', $body) && array_key_exists('data', $body);
            if ($has_envelope) {
                $payload = is_array($body['data']) ? $body['data'] : array();
                $success = (bool) $body['success'];
                $valid = isset($payload['valid']) ? (bool) $payload['valid'] : $success;
                $message = isset($body['message']) ? $body['message'] : ($payload['message'] ?? '');

                // Capture signed token if provided by V2 server
                $signed_token = $payload['signed_token'] ?? ($payload['token'] ?? '');
                if (!empty($signed_token)) {
                    update_option('kdsamref_pro_signed_token', $signed_token);
                }

                // Prefer domain from payload; fallback to common fields or current domain
                $domain_from_payload = $payload['domain'] ?? ($payload['aud'] ?? ($payload['site_url'] ?? ($payload['site'] ?? '')));
                $result = array(
                    'valid' => $valid,
                    'message' => $message,
                    'status' => $payload['status'] ?? ($valid ? 'active' : 'invalid'),
                    'expiry_date' => $payload['expiry_date'] ?? '',
                    'subscription_type' => $payload['subscription_type'] ?? '',
                    'customer_name' => $payload['customer_name'] ?? ($payload['customer']['name'] ?? ''),
                    'customer_email' => $payload['customer_email'] ?? ($payload['customer']['email'] ?? ''),
                    'usage_count' => $payload['usage_count'] ?? 0,
                    'max_usage' => $payload['max_usage'] ?? -1,
                    'domain' => !empty($domain_from_payload) ? $this->normalize_domain($domain_from_payload) : $this->get_current_domain(),
                    'signed_token' => $signed_token,
                );
                return $result;
            }

            // Legacy direct payload without envelope
            $valid = !empty($body['valid']);
            // Capture signed token for legacy payload if present
            if (!empty($body['signed_token'] ?? '')) {
                update_option('kdsamref_pro_signed_token', $body['signed_token']);
            }
            $domain_from_body = $body['domain'] ?? ($body['aud'] ?? ($body['site_url'] ?? ($body['site'] ?? '')));
            return array(
                'valid' => $valid,
                'message' => $body['message'] ?? '',
                'status' => $body['status'] ?? ($valid ? 'active' : 'invalid'),
                'expiry_date' => $body['expiry_date'] ?? '',
                'subscription_type' => $body['subscription_type'] ?? '',
                'customer_name' => $body['customer_name'] ?? ($body['customer']['name'] ?? ''),
                'customer_email' => $body['customer_email'] ?? ($body['customer']['email'] ?? ''),
                'usage_count' => $body['usage_count'] ?? 0,
                'max_usage' => $body['max_usage'] ?? -1,
                'domain' => !empty($domain_from_body) ? $this->normalize_domain($domain_from_body) : $this->get_current_domain(),
                'signed_token' => $body['signed_token'] ?? '',
            );
        }

        // Unexpected response
        if (defined('WP_DEBUG') && WP_DEBUG) {
            error_log('WRO Pro: License server unexpected response code=' . $code . ' body=' . substr($raw_body, 0, 500));
        }
        return array('valid' => false, 'message' => __('License server error', 'kds-report-for-orderable-pro'), 'license_key' => $license_key);
    }

    private function collect_site_data() {
        global $wp_version;
        $wc_version = '';
        if (function_exists('WC')) {
            $wc_version = WC()->version;
        }
        return array(
            'wp_version' => $wp_version,
            'php_version' => PHP_VERSION,
            'wc_version' => $wc_version,
            'plugin_version' => $this->version,
            'site_url' => home_url(),
            'admin_email' => get_option('admin_email'),
            'site_language' => get_locale(),
            'timezone' => wp_timezone_string(),
            'theme' => wp_get_theme()->get('Name'),
            'server_software' => $_SERVER['SERVER_SOFTWARE'] ?? '',
            'multisite' => is_multisite(),
            'ssl' => is_ssl(),
        );
    }

    private function get_current_domain() {
        $domain = '';
        if (function_exists('home_url')) {
            $domain = parse_url(home_url(), PHP_URL_HOST);
        }
        if (empty($domain) && !empty($_SERVER['HTTP_HOST'])) {
            $domain = $_SERVER['HTTP_HOST'];
        }
        if (empty($domain)) {
            $domain = 'localhost';
        }
        if (strpos($domain, 'www.') === 0) {
            $domain = substr($domain, 4);
        }
        return $domain;
    }

    private function normalize_domain($value) {
        // Accept full URLs or hostnames; return bare host
        if (empty($value)) {
            return $this->get_current_domain();
        }
        if (filter_var($value, FILTER_VALIDATE_URL)) {
            $host = parse_url($value, PHP_URL_HOST);
        } else {
            // If it looks like host already
            $host = $value;
        }
        if (strpos($host, 'www.') === 0) {
            $host = substr($host, 4);
        }
        return $host ?: $this->get_current_domain();
    }

    private function get_client_ip() {
        $keys = array('HTTP_CLIENT_IP', 'HTTP_X_FORWARDED_FOR', 'REMOTE_ADDR');
        foreach ($keys as $key) {
            if (!empty($_SERVER[$key])) {
                return sanitize_text_field(is_array($_SERVER[$key]) ? $_SERVER[$key][0] : $_SERVER[$key]);
            }
        }
        return '';
    }

    private function clear_license_cache() {
        delete_transient($this->cache_key);
        delete_option('kdsamref_pro_license_status');
    }
}