<?php

namespace Kanzu\StoreVoiceAI;

// Prevent direct file access.
if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

use Kanzu\StoreVoiceAI\Services\Product_Sync;
use Kanzu\StoreVoiceAI\Services\Store_Voice_AI_API;

class Hook_Registry
{

	public function __construct()
	{
		$this->register_hooks();
	}

	public function register_hooks()
	{

		// Sync license state with the backend whenever Freemius activates/deactivates one.
		storevoiceai_fs()->add_action('after_license_activation', [$this, 'on_license_activation']);
		storevoiceai_fs()->add_action('after_license_deactivation', [$this, 'on_license_deactivation']);

		// Add API Endpoints
		$api_endpoints = new API_Endpoints();
		add_action('rest_api_init', [$api_endpoints, 'register_custom_voice_endpoints']);

		// Enqueue storefront/admin assets for the call widget.
		$scripts = new Scripts();
		add_action('wp_enqueue_scripts', [$scripts, 'enqueue_scripts']);
		add_action('admin_enqueue_scripts', [$scripts, 'enqueue_scripts']);

		// call widget
		$call_widget = new Call_Widget();
		add_action('wp_footer', [$call_widget, 'render']);
		add_action('admin_footer', [$call_widget, 'render']);

		add_action('wp_ajax_storevoiceai_create_call', [$call_widget, 'create_call']);
		add_action('wp_ajax_nopriv_storevoiceai_create_call', [$call_widget, 'create_call']);

		// Add  Admin Menu Pages
		$admin_page = new Storevoiceai_Admin_Page();
		add_action('admin_menu', array($admin_page, 'add_admin_menu'));

		// Register scripts and styles
		add_action('admin_enqueue_scripts', array($admin_page, 'enqueue_admin_assets'));

		// Add AJAX handlers
		add_action('wp_ajax_storevoiceai_get_call_logs', array($admin_page, 'get_call_logs'));
		add_action('wp_ajax_storevoiceai_sync_calls', array($admin_page, 'sync_calls'));
		add_action('wp_ajax_storevoiceai_get_call_details', array($admin_page, 'get_call_details'));
		add_action('wp_ajax_storevoiceai_get_call_summary', array($admin_page, 'get_call_summary'));
		add_action('wp_ajax_storevoiceai_get_voice_usage', array($admin_page, 'get_voice_usage'));
		add_action('wp_ajax_storevoiceai_get_voice_usage_daily', array($admin_page, 'get_voice_usage_daily'));
		add_action('wp_ajax_storevoiceai_get_billing_connection_status', array($admin_page, 'get_billing_connection_status'));
		add_action('wp_ajax_storevoiceai_get_wallet_transactions', array($admin_page, 'get_wallet_transactions'));
		add_action('wp_ajax_storevoiceai_create_stripe_top_up_session', array($admin_page, 'create_stripe_top_up_session'));
		add_action('wp_ajax_storevoiceai_create_voice_assistant', array($admin_page, 'create_voice_assistant'));

		add_action('wp_ajax_storevoiceai_get_phone_numbers', array($admin_page, 'handle_get_phone_numbers'));
		add_action('wp_ajax_storevoiceai_purchase_phone_number', array($admin_page, 'handle_purchase_phone_number'));
		add_action('wp_ajax_storevoiceai_delete_phone_number', array($admin_page, 'handle_delete_phone_number'));

		add_action('wp_ajax_storevoiceai_get_knowledge_base_pages', array($admin_page, 'get_knowledge_base_pages'));
		add_action('wp_ajax_storevoiceai_create_knowledge_base_pages', array($admin_page, 'create_knowledge_base_pages'));

		add_action('wp_ajax_storevoiceai_get_voices',         array($admin_page, 'get_voices'));
		add_action('wp_ajax_storevoiceai_update_agent_voice', array($admin_page, 'update_agent_voice'));

		add_action('wp_ajax_storevoiceai_dismiss_dashboard_tour', array($admin_page, 'dismiss_dashboard_tour'));

		// Notify the backend on WooCommerce product create/update/delete so it
		// can re-pull the product into its knowledge base.
		$product_sync = new Product_Sync();
		$product_sync->register_hooks();

		// First-run onboarding wizard.
		$onboarding = new Onboarding();
		$onboarding->register_hooks();
	}

	function trigger_woocommerce_export()
	{
		// Required for export functionality
		require_once(ABSPATH . 'wp-admin/includes/export.php');

		// Set up export arguments for WooCommerce products
		$args = array(
			'content' => 'product',      // Export WooCommerce products
			'status' => 'publish',       // Only published products
			'author' => false,           // All authors
			'start_date' => false,       // All dates
			'end_date' => false,
			'category' => false,         // All categories
		);

		// Buffer the output
		ob_start();
		export_wp($args);
		$xml = ob_get_clean();

		$api = new Store_Voice_AI_API();
		$api->export_product_list($xml);
		return array(
			'success' => true,
			'message' => 'Export completed and sent to backend'
		);
	}


	public function redirect_after_activation()
	{
		// Check if this is the admin panel to make sure it runs in the right context
		if (is_admin()) {
			// Redirect to the pricing page after activation
			wp_safe_redirect(admin_url('admin.php?page=storevoiceai-for-woocommerce-pricing'));
			exit; // Always call exit after a redirect
		}
	}

	public function on_license_activation($status)
	{
		self::sync_license_state();
	}

	public function on_license_deactivation($status)
	{
		self::sync_license_state();
	}

	/**
	 * Reconciles backend license state with Freemius. Safe to call repeatedly.
	 * Only hits the backend when the locally-cached license differs from what
	 * Freemius currently reports, so this is cheap to run on every admin page load.
	 */
	public static function sync_license_state()
	{
		if (!function_exists('\\Kanzu\\StoreVoiceAI\\storevoiceai_fs')) {
			return;
		}
		$fs = \Kanzu\StoreVoiceAI\storevoiceai_fs();
		if (!$fs) {
			return;
		}

		$current = self::get_current_license_secret_key($fs);
		$last    = get_option('_storevoiceai_last_synced_license', '__unset__');
		if (is_string($current)) {
			$current = trim($current);
		}

		// Coerce both sides to a comparable form (null === no license).
		$last_normalized = ($last === '__unset__' || $last === '') ? null : $last;

		if (empty($current)) {
			if ($last_normalized !== null) {
				update_option('_storevoiceai_last_synced_license', '', false);
			}
			return;
		}

		if ($current === $last_normalized) {
			return;
		}

		// Only sync once we've registered with the backend — otherwise we have no auth token.
		if (!get_option('_storevoiceai_site_registered')) {
			return;
		}

		$response = (new Store_Voice_AI_API())->sync_license($current);
		if (is_wp_error($response)) {
			return;
		}
		update_option('_storevoiceai_last_synced_license', $current ?: '', false);
	}

	private static function get_current_license_secret_key($fs)
	{
		if (method_exists($fs, 'has_active_valid_license') && !$fs->has_active_valid_license()) {
			return null;
		}

		if (!method_exists($fs, '_get_license')) {
			return null;
		}

		$sdk_version = method_exists($fs, 'get_sdk_version')
			? $fs->get_sdk_version()
			: (defined('WP_FS__SDK_VERSION') ? WP_FS__SDK_VERSION : 'unknown');

		if ($sdk_version !== 'unknown' && version_compare($sdk_version, '2.0.0', '<')) {
			return null;
		}

		// Freemius exposes license validity publicly, but not secret_key; guarded SDK 2.x fallback is needed for backend sync.
		self::log_private_license_fallback($sdk_version);
		$license = $fs->_get_license();

		return ($license && !empty($license->secret_key)) ? $license->secret_key : null;
	}

	private static function log_private_license_fallback($sdk_version)
	{
		$option_key = '_storevoiceai_logged_freemius_license_fallback_' . sanitize_key((string) $sdk_version);
		if (get_option($option_key)) {
			return;
		}

		update_option($option_key, 1, false);
	}

	public static function register_site_with_backend()
	{
		$api        = new Store_Voice_AI_API();
		$site_title = get_bloginfo('name');
		$site_url   = site_url();

		// Resolve a user_id for the WC API key. Prefer the current admin; fall back
		// to the first available admin so this works during background admin_init runs.
		$user_id = get_current_user_id();
		if (!$user_id) {
			$admins  = get_users(['role' => 'administrator', 'number' => 1, 'fields' => 'ID']);
			$user_id = !empty($admins) ? (int) $admins[0] : 0;
		}

		if (!$user_id) {
			return;
		}

		$wc_api_keys = self::generate_wc_api_keys($user_id);
		if (!$wc_api_keys) {
			return;
		}

		$description = __('StoreVoiceAI Integration', 'storevoiceai-for-woocommerce');

		// Owner email: prefer the site's Administration Email (Settings → General),
		// falling back to the resolved admin user's email if that's somehow unset.
		$owner_email = get_option('admin_email');
		if (empty($owner_email)) {
			$user = get_userdata($user_id);
			if ($user && !empty($user->user_email)) {
				$owner_email = $user->user_email;
			}
		}

		$agent_name = get_option('_storevoiceai_assistant_name', 'Grace');

		$response = $api->register_site(
			$site_title,
			$site_url,
			$wc_api_keys['consumer_key'],
			$wc_api_keys['consumer_secret'],
			$description,
			$owner_email,
			$agent_name
		);

		if (is_wp_error($response) || empty($response['siteKey'])) {
			// Leave the needs_registration flag set so admin_init retries on the next request.
			return;
		}

		update_option('_storevoiceai_site_key', $response['siteKey'], false);

		if (!empty($response['agentId']) || !empty($response['agent_id'])) {
			update_option('_storevoiceai_agentid', $response['agentId'] ?? $response['agent_id'], false);
		}
		if (!empty($response['systemUser']['email'])) {
			update_option('_storevoiceai_system_email', $response['systemUser']['email'], false);
		}

		update_option('_storevoiceai_site_registered', 1, false);
		delete_option('_storevoiceai_needs_registration');
	}

	private static function generate_wc_api_keys($user_id)
	{
		// Ensure WooCommerce is active and required functions exist
		if (!function_exists('wc_rand_hash') || !class_exists('WooCommerce')) {
			return false;
		}

		global $wpdb;
		$table_name = $wpdb->prefix . 'woocommerce_api_keys';
		$description = __('StoreVoiceAI Integration', 'storevoiceai-for-woocommerce');

		// Generate raw keys
		$consumer_key    = 'ck_' . wc_rand_hash();
		$consumer_secret = 'cs_' . wc_rand_hash();

		// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter -- Direct DB access is required to create WooCommerce REST API keys; WooCommerce exposes no API for this. The table name derives from $wpdb->prefix and all values use prepare()/format arrays.
		$existing_key_id = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT key_id FROM {$table_name} WHERE user_id = %d AND description = %s LIMIT 1",
				$user_id,
				$description
			)
		);

		if ($existing_key_id) {
			$result = $wpdb->update(
				$table_name,
				array(
					'description'     => $description,
					'permissions'     => 'read_write',
					'consumer_key'    => wc_api_hash($consumer_key),
					'consumer_secret' => $consumer_secret,
					'truncated_key'   => substr($consumer_key, -7),
				),
				array(
					'key_id'  => (int) $existing_key_id,
					'user_id' => $user_id,
				),
				array('%s', '%s', '%s', '%s', '%s'),
				array('%d', '%d')
			);

			if ($result !== false) {
				return array(
					'consumer_key'    => $consumer_key,
					'consumer_secret' => $consumer_secret,
				);
			}

			return false;
		}

		$result = $wpdb->insert(
			$table_name,
			array(
				'user_id'         => $user_id,
				'description'     => $description,
				'permissions'     => 'read_write',
				'consumer_key'    => wc_api_hash($consumer_key),
				'consumer_secret' => $consumer_secret,
				'truncated_key'   => substr($consumer_key, -7),
			),
			array('%d', '%s', '%s', '%s', '%s', '%s')
		);
		// phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared, PluginCheck.Security.DirectDB.UnescapedDBParameter

		if ($result) {
			return array(
				'consumer_key'    => $consumer_key,
				'consumer_secret' => $consumer_secret,
			);
		}

		return false;
	}
}
