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

/**
 * VMO Client Sync Core
 *
 * Runs inside QuickLaunch, Direct, and staging client builds. This is the
 * production version of the temporary receiver: it self-registers, heartbeats,
 * pulls entitlement/discount sync commands, applies them locally, and reports
 * results back to Master. No manual customer registration is required.
 */
class VMO_Client_Sync_Core {
    const VERSION = '1.0.1';
    private static $instance = null;

    public static function boot() {
        if (defined('VMO_MASTER_VERSION') && VMO_MASTER_VERSION === true && !(defined('VMO_CLIENT_MODE') && VMO_CLIENT_MODE === true)) {
            return;
        }
        if (!self::$instance) self::$instance = new self();
        return self::$instance;
    }

    private function __construct() {
        add_action('init', array($this, 'ensure_bootstrap'), 3);
        add_action('init', array($this, 'schedule_cron'), 20);
        add_action('admin_init', array($this, 'maybe_register_on_admin'), 6);
        add_action('vmo_client_sync_core_cron', array($this, 'cron_tick'));
    }

    public function ensure_bootstrap() {
        if (!get_option('vmo_client_instance_uuid')) {
            $installation_id = trim((string) get_option('vmo_installation_id', ''));
            update_option('vmo_client_instance_uuid', $installation_id !== '' ? $installation_id : ('vmo_inst_' . wp_generate_uuid4()), false);
        }
        if (!get_option('vmo_client_instance_type')) {
            $channel = defined('VMO_CLIENT_DISTRIBUTION_CHANNEL') ? (string) VMO_CLIENT_DISTRIBUTION_CHANNEL : (string) get_option('vmo_client_distribution_channel', 'direct_wordpress');
            $type = stripos($channel, 'quicklaunch') !== false || stripos($channel, 'hosted') !== false ? 'quicklaunch' : 'direct';
            if ((string) get_option('vmo_environment', '') === 'staging') $type = 'staging';
            update_option('vmo_client_instance_type', $type, false);
        }
        if (!get_option('vmo_client_environment')) {
            $env = (defined('WP_ENVIRONMENT_TYPE') && WP_ENVIRONMENT_TYPE) ? WP_ENVIRONMENT_TYPE : 'production';
            update_option('vmo_client_environment', sanitize_key((string) $env), false);
        }
        if (!get_option('vmo_client_master_url')) {
            update_option('vmo_client_master_url', $this->derive_master_site_url(), false);
        }
    }

    public function schedule_cron() {
        if (!wp_next_scheduled('vmo_client_sync_core_cron')) {
            wp_schedule_event(time() + 300, 'hourly', 'vmo_client_sync_core_cron');
        }
    }

    public function maybe_register_on_admin() {
        if (!is_admin()) return;
        if (!current_user_can('manage_options')) return;
        if (get_option('vmo_client_instance_secret')) {
            if (!get_transient('vmo_client_sync_recent_admin_tick')) {
                set_transient('vmo_client_sync_recent_admin_tick', 1, 10 * MINUTE_IN_SECONDS);
                $this->heartbeat();
                $this->pull_and_apply();
            }
            return;
        }
        if (get_transient('vmo_client_sync_auto_register_attempted')) return;
        set_transient('vmo_client_sync_auto_register_attempted', 1, 15 * MINUTE_IN_SECONDS);
        $this->register_instance();
    }

    public function cron_tick() {
        if (!get_option('vmo_client_instance_secret')) {
            $this->register_instance();
        }
        $this->heartbeat();
        $this->pull_and_apply();
    }

    private function derive_master_site_url() {
        $proxy = defined('VMO_MASTER_PROXY_URL') ? (string) VMO_MASTER_PROXY_URL : (string) get_option('vmo_master_proxy_url', 'https://getvmo.com/wp-json/vmo-builder/v1/proxy');
        $proxy = trim($proxy);
        if ($proxy === '') return 'https://getvmo.com';
        $parts = wp_parse_url($proxy);
        if (!empty($parts['scheme']) && !empty($parts['host'])) {
            return $parts['scheme'] . '://' . $parts['host'];
        }
        return untrailingslashit(str_replace('/wp-json/vmo-builder/v1/proxy', '', $proxy));
    }

    private function master_endpoint($path) {
        return untrailingslashit((string) get_option('vmo_client_master_url', $this->derive_master_site_url())) . '/wp-json/vmo-master/v1' . $path;
    }

    private function sync_secret() {
        if (defined('VMO_CLIENT_SYNC_SECRET') && VMO_CLIENT_SYNC_SECRET) return (string) VMO_CLIENT_SYNC_SECRET;
        return (string) get_option('vmo_client_sync_secret', '');
    }

    private function owner_email() {
        $stored = sanitize_email((string) get_option('vmo_client_owner_email', ''));
        if ($stored !== '') return $stored;
        $admin = get_option('admin_email', '');
        return sanitize_email((string) $admin);
    }

    private function owner_user_id() {
        $stored = absint(get_option('vmo_client_owner_user_id', 0));
        if ($stored > 0) return $stored;
        $admins = get_users(array('role'=>'administrator','number'=>1,'fields'=>'ID'));
        return !empty($admins) ? absint($admins[0]) : 0;
    }

    private function base_payload() {
        return array(
            'instance_uuid'=>(string) get_option('vmo_client_instance_uuid', ''),
            'instance_secret'=>(string) get_option('vmo_client_instance_secret', ''),
            'instance_type'=>sanitize_key((string) get_option('vmo_client_instance_type', 'direct')),
            'environment'=>sanitize_key((string) get_option('vmo_client_environment', 'production')),
            'site_url'=>home_url('/'),
            'owner_user_id'=>$this->owner_user_id(),
            'owner_email'=>$this->owner_email(),
            'license_key'=>(string) get_option('vmo_license_key', ''),
            'installation_id'=>(string) get_option('vmo_installation_id', ''),
            'distribution_channel'=>(string) get_option('vmo_client_distribution_channel', (defined('VMO_CLIENT_DISTRIBUTION_CHANNEL') ? VMO_CLIENT_DISTRIBUTION_CHANNEL : 'direct_wordpress')),
            'plugin_version'=>defined('VMO_AI_BUILDER_VERSION') ? VMO_AI_BUILDER_VERSION : self::VERSION,
            'sync_core_version'=>self::VERSION,
            'wordpress_version'=>get_bloginfo('version'),
        );
    }

    public function register_instance() {
        $payload = $this->base_payload();
        if (empty($payload['instance_uuid'])) {
            $payload['instance_uuid'] = !empty($payload['installation_id']) ? $payload['installation_id'] : ('vmo_inst_' . wp_generate_uuid4());
            update_option('vmo_client_instance_uuid', $payload['instance_uuid'], false);
        }
        $headers = array('Content-Type'=>'application/json','Accept'=>'application/json');
        if ($this->sync_secret() !== '') $headers['X-VMO-CLIENT-SYNC-SECRET'] = $this->sync_secret();
        if (!empty($payload['license_key'])) $headers['X-VMO-License'] = $payload['license_key'];
        if (!empty($payload['installation_id'])) $headers['X-VMO-Installation'] = $payload['installation_id'];
        $json = $this->post('/client/register', $payload, $headers);
        if (!empty($json['success'])) {
            update_option('vmo_client_instance_uuid', sanitize_text_field((string) $json['instance_uuid']), false);
            update_option('vmo_client_instance_secret', sanitize_text_field((string) $json['instance_secret']), false);
            update_option('vmo_client_sync_last_registered_at', current_time('mysql'), false);
        }
        update_option('vmo_client_sync_last_status', $json, false);
        return $json;
    }

    public function heartbeat() {
        if (!get_option('vmo_client_instance_secret')) return array('success'=>false,'message'=>'Client is not registered yet.');
        $payload = $this->base_payload();
        $payload['status'] = 'online';
        $json = $this->client_post('/client/heartbeat', $payload);
        if (!empty($json['success'])) update_option('vmo_client_sync_last_heartbeat_at', current_time('mysql'), false);
        update_option('vmo_client_sync_last_status', $json, false);
        return $json;
    }

    public function pull_and_apply() {
        if (!get_option('vmo_client_instance_secret')) {
            $reg = $this->register_instance();
            if (empty($reg['success'])) return $reg;
        }
        $json = $this->client_post('/client/sync/pull', array('instance_uuid'=>get_option('vmo_client_instance_uuid')));
        $applied = array();
        if (!empty($json['success']) && !empty($json['items']) && is_array($json['items'])) {
            foreach ($json['items'] as $item) {
                $result = $this->apply_sync_item($item);
                $this->ack_sync_item((string)($item['queue_uuid'] ?? ''), !empty($result['success']) ? 'applied' : 'failed', (string)($result['message'] ?? ''));
                $applied[] = array('queue_uuid'=>$item['queue_uuid'] ?? '', 'result'=>$result);
            }
            update_option('vmo_client_sync_last_sync_at', current_time('mysql'), false);
        }
        $json['applied_results'] = $applied;
        update_option('vmo_client_sync_last_status', $json, false);
        return $json;
    }

    private function client_post($path, $payload) {
        return $this->post($path, $payload, array(
            'Content-Type'=>'application/json',
            'Accept'=>'application/json',
            'X-VMO-INSTANCE-UUID'=>(string) get_option('vmo_client_instance_uuid', ''),
            'X-VMO-INSTANCE-SECRET'=>(string) get_option('vmo_client_instance_secret', ''),
        ));
    }

    private function post($path, $payload, $headers) {
        $response = wp_remote_post($this->master_endpoint($path), array('timeout'=>20, 'headers'=>$headers, 'body'=>wp_json_encode($payload)));
        if (is_wp_error($response)) return array('success'=>false,'message'=>$response->get_error_message(),'diagnosis'=>'wp_remote_error');
        $code = wp_remote_retrieve_response_code($response);
        $body = wp_remote_retrieve_body($response);
        $json = json_decode($body, true);
        if (!is_array($json)) $json = array('success'=>false,'message'=>'Master returned non-JSON response.','response_excerpt'=>substr(wp_strip_all_tags($body),0,700));
        $json['http_code'] = $code;
        return $json;
    }

    private function apply_sync_item($item) {
        $command = sanitize_key((string)($item['command'] ?? ''));
        $payload = isset($item['payload']) && is_array($item['payload']) ? $item['payload'] : array();
        if ($command === 'apply_discount') return $this->apply_discount_payload($payload);
        return array('success'=>false,'message'=>'Unsupported sync command: '.$command);
    }

    private function apply_discount_payload($payload) {
        $user_id = absint($payload['user_id'] ?? $this->owner_user_id());
        $discount_code = sanitize_text_field((string)($payload['discount_code'] ?? ''));
        $discount_type = sanitize_key((string)($payload['discount_type'] ?? ''));
        $discount_value = (float)($payload['discount_value'] ?? 0);
        $expires_at = sanitize_text_field((string)($payload['expires_at'] ?? ''));
        update_option('vmo_active_discount_code', $discount_code, false);
        update_option('vmo_active_discount_type', $discount_type, false);
        update_option('vmo_active_discount_value', $discount_value, false);
        update_option('vmo_discount_expires_at', $expires_at, false);
        update_option('vmo_entitlement_last_sync', current_time('mysql'), false);
        if ($user_id > 0) {
            update_user_meta($user_id, 'vmo_active_discount_code', $discount_code);
            update_user_meta($user_id, 'vmo_active_discount_type', $discount_type);
            update_user_meta($user_id, 'vmo_active_discount_value', $discount_value);
            update_user_meta($user_id, 'vmo_discount_expires_at', $expires_at);
            update_user_meta($user_id, 'vmo_entitlement_status', 'active');
        }
        return array('success'=>true,'message'=>'Discount applied locally.','discount_code'=>$discount_code,'discount_type'=>$discount_type,'discount_value'=>$discount_value,'expires_at'=>$expires_at,'user_id'=>$user_id);
    }

    private function ack_sync_item($queue_uuid, $status, $message) {
        if ($queue_uuid === '') return;
        $this->client_post('/client/sync/ack', array('queue_uuid'=>$queue_uuid,'status'=>$status,'message'=>$message));
    }
}
