<?php

namespace CommerceBird;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

require_once ABSPATH . 'wp-admin/includes/upgrade.php';

use CommerceBird\Admin\Actions\Ajax\ExactOnlineAjax;
use CommerceBird\Admin\Actions\Ajax\ZohoInventoryAjax;
use CommerceBird\Admin\Actions\Ajax\ZohoCRMAjax;
use CommerceBird\Admin\Actions\Ajax\AcfAjax;
use CommerceBird\Admin\Actions\Ajax\SettingsAjax;
use CommerceBird\Admin\Template;
use CommerceBird\Admin\Cmbird_Acf;
use CommerceBird\CMBIRD_AI_Product_Blocks_Block;
use CommerceBird\CMBIRD_AI_Product_Blocks_Cron;
use CommerceBird\CMBIRD_AI_Product_Blocks_Display;
use CommerceBird\Cmbird_WC_API;
use CMBIRD_Purchase_Orders_Automation;

/**
 * Main plugin class for CommerceBird.
 *
 * Handles activation, deactivation, uninstall, and initialization logic.
 *
 * @since 1.0.0
 */
class Plugin {


	/**
	 * The constructor for the plugin.
	 *
	 * @since 1.0.0
	 *
	 * This function is called when the plugin is loaded. It hooks the init method to the admin_init action.
	 */
	public function __construct() {
		add_action( 'admin_init', array( $this, 'init' ) );
	}

	/**
	 * Plugin activation handler.
	 *
	 * - Installs the MU CLI helper.
	 * - Ensures the "vendor" role exists.
	 * - Creates {$wpdb->prefix}cmbird_zi_category_map via dbDelta (idempotent).
	 *
	 * @since 1.0.0
	 */
	public static function activate() {
		// Copy CLI script to mu-plugins folder for automatic loading.
		self::install_mu_plugin();
		CMBIRD_AI_Product_Blocks_Cron::activate();
		// Create the "vendor" role — must run at activation, not on every init.
		if ( ! get_role( 'vendor' ) ) {
			add_role(
				'vendor',
				__( 'Vendor', 'commercebird' ),
				array( 'read' => true )
			);
		}

		self::ensure_zi_category_map_table();
	}

	/**
	 * Ensure the Zoho category mapping table exists.
	 *
	 * Uses dbDelta so it is safe to call repeatedly on activation and upgrades.
	 *
	 * @since 2.9.2
	 * @return void
	 */
	public static function ensure_zi_category_map_table() {
		global $wpdb;
		$charset_collate = $wpdb->get_charset_collate();
		$table           = $wpdb->prefix . 'cmbird_zi_category_map';
		$sql             = "CREATE TABLE {$table} (
			id BIGINT UNSIGNED NOT NULL AUTO_INCREMENT,
			wc_term_id BIGINT UNSIGNED NOT NULL,
			zoho_category_id VARCHAR(64) NOT NULL,
			source ENUM('auto','manual') NOT NULL DEFAULT 'auto',
			status ENUM('active','orphan','review') NOT NULL DEFAULT 'active',
			review_reason VARCHAR(64) NULL,
			created_at DATETIME NOT NULL,
			updated_at DATETIME NOT NULL,
			last_verified_at DATETIME NULL,
			PRIMARY KEY  (id),
			UNIQUE KEY uniq_wc_term_active (wc_term_id, status),
			UNIQUE KEY uniq_zoho_id_active (zoho_category_id, status),
			KEY status_idx (status)
		) $charset_collate;";
		dbDelta( $sql );
	}

	/**
	 * Copy the CLI script to mu-plugins folder.
	 *
	 * @since 2.6.5
	 */
	private static function install_mu_plugin() {
		$mu_plugins_dir = WP_CONTENT_DIR . '/mu-plugins';
		$source_file    = CMBIRD_PATH . 'mu-plugins/cmbird-media-cleanup-cli.php';
		$dest_file      = $mu_plugins_dir . '/cmbird-media-cleanup-cli.php';

		// Create mu-plugins directory if it doesn't exist.
		if ( ! is_dir( $mu_plugins_dir ) ) {
			wp_mkdir_p( $mu_plugins_dir );
		}

		// Copy the file if source exists and destination doesn't or is outdated.
		if ( file_exists( $source_file ) ) {
			if ( ! file_exists( $dest_file ) || filemtime( $source_file ) > filemtime( $dest_file ) ) {
				copy( $source_file, $dest_file );
			}
		}
	}

	/**
	 * Clear all the scheduled actions when the plugin is deactivated.
	 *
	 * @since 1.0.0
	 */
	public static function deactivate() {
		CMBIRD_AI_Product_Blocks_Cron::deactivate();
		wp_clear_scheduled_hook( 'zi_execute_import_sync' );
		wp_clear_scheduled_hook( 'cmbird_eo_get_payment_statuses' );
		wp_clear_scheduled_hook( 'cmbird_exact_online_sync_orders' );
		wp_clear_scheduled_hook( 'cmbird_eo_product_mapping_daily' );
		wp_clear_scheduled_hook( 'cmbird_zoho_sync_category_cron' );
		wp_clear_scheduled_hook( 'cmbird_zoho_contact_sync' );
	}

	/**
	 * Deletes all the options and post/user meta set by the plugin.
	 *
	 * This function is called when the plugin is uninstalled.
	 *
	 * @since 1.0.0
	 */
	public static function uninstall() {
		$post_meta_keys = array(
			'zi_item_id',
			'zi_purchase_account_id',
			'zi_account_id',
			'zi_account_name',
			'zi_inventory_account_id',
			'zi_salesorder_id',
			'zi_category_id',
			'_cost_price',
			'eo_item_id',
		);
		$user_meta_keys = array(
			'zi_contact_id',
			'zi_primary_contact_id',
			'zi_created_time',
			'zi_last_modified_time',
			'zi_billing_address_id',
			'zi_shipping_address_id',
			'zi_contact_persons_id',
			'zi_currency_id',
			'zi_currency_code',
			'eo_contact_id',
			'eo_account_id',
			'eo_gl_account',
		);
		$zi_option_keys = array(
			'cmbird_zi_webhook_password',
			'cmbird_zoho_inventory_cron_class',
			'cmbird_zoho_sync_status',
			'cmbird_zoho_item_category',
			'cmbird_zoho_stock_sync_status',
			'cmbird_zoho_item_name_sync_status',
			'cmbird_zoho_enable_auto_no_status',
			'cmbird_zoho_product_sync_status',
			'cmbird_zoho_disable_image_sync_status',
			'cmbird_zoho_disable_price_sync_status',
			'cmbird_zoho_disable_name_sync_status',
			'cmbird_zoho_disable_description_sync_status',
			'cmbird_zoho_enable_accounting_stock_status',
			'cmbird_zoho_enable_order_status',
			'cmbird_wootozoho_custom_fields',
			'cmbird_zoho_pricelist_id',
			'cmbird_zoho_location_id_status',
			'cmbird_zoho_inventory_auth_code',
			'cmbird_zoho_inventory_access_token',
			'cmbird_zoho_inventory_refresh_token',
			'cmbird_zoho_inventory_timestamp',
			'cmbird_zoho_inventory_oid',
			'cmbird_zoho_inventory_url',
			'cmbird_zoho_inventory_cid',
			'cmbird_zoho_inventory_cs',
			'cmbird_zoho_inventory_domain',
			'cmbird_authorization_redirect_uri',
			'cmbird_zoho_crm_auth_code',
			'cmbird_zoho_crm_access_token',
			'cmbird_zoho_crm_refresh_token',
			'cmbird_zoho_crm_timestamp',
			'cmbird_location_data',
			'cmbird_ai_review_summary_enabled',
			'cmbird_ai_review_summary_prompt',
			'cmbird_ai_content_writer_enabled',
			'cmbird_ai_shopping_experience_enabled',
			'cmbird_eo_product_cron_enabled',
		);

		foreach ( $zi_option_keys as $zi_option ) {
			delete_option( $zi_option );
		}

		foreach ( $post_meta_keys as $post_key ) {
			delete_post_meta_by_key( $post_key );
		}

		$users = get_users(
			array(
				'fields' => array( 'ID' ),
			)
		);
		foreach ( $users as $user_id ) {
			foreach ( $user_meta_keys as $user_key ) {
				delete_user_meta( $user_id, $user_key );
			}
		}
		// Drop the category mapping table.
		global $wpdb;
		$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}cmbird_zi_category_map" ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared

		// Clean up any legacy mapping options (covers installs that never ran the migration).
		$wpdb->query(
			"DELETE FROM {$wpdb->options} WHERE option_name LIKE 'cmbird_zoho_id_for_term_id_%'" // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
		);

		// And the migration flags.
		delete_option( 'cmbird_zi_category_map_migrated' );
		delete_option( 'cmbird_zi_category_map_legacy_purged' );
		// clear scheduled zcrm_refresh_token.
		wp_clear_scheduled_hook( 'zcrm_refresh_token' );

		// Remove the mu-plugin file.
		$mu_plugin_file = WP_CONTENT_DIR . '/mu-plugins/cmbird-media-cleanup-cli.php';
		if ( file_exists( $mu_plugin_file ) ) {
			wp_delete_file( $mu_plugin_file );
		}
	}

	/**
	 * Initializes the plugin.
	 *
	 * Removes the option for Zoho Inventory access token if it contains only one character.
	 * Schedules a cronjob for import sync if the access token is not empty and the interval is not set to 'none'.
	 * Creates the webhook password if it does not exist.
	 * Loads the necessary Ajax handlers and templates.
	 *
	 * @since 1.0.0
	 */
	public static function init() {
		new CMBIRD_AI_Product_Blocks_Cron();
		new CMBIRD_AI_Product_Blocks_Display();
		new CMBIRD_AI_Product_Blocks_Block();

		if ( is_admin() ) {
			$zoho_inventory_access_token = get_option( 'cmbird_zoho_inventory_access_token' );
			// remove option zoho_inventory_access_token if it contains only one character.
			if ( $zoho_inventory_access_token && strlen( $zoho_inventory_access_token ) === 1 ) {
				delete_option( 'cmbird_zoho_inventory_access_token' );
			} else {
				// schedule cronjob for import sync.
				$interval = get_option( 'zi_cron_interval' );
				if ( 'none' !== $interval && ! empty( $zoho_inventory_access_token ) ) {
					if ( ! wp_next_scheduled( 'zi_execute_import_sync' ) ) {
						wp_schedule_event( time(), $interval, 'zi_execute_import_sync' );
					}
				} else {
					wp_clear_scheduled_hook( 'zi_execute_import_sync' );
				}
			}
			// create webhook password if does not exists.
			if ( ! get_option( 'cmbird_zi_webhook_password', false ) ) {
				add_option( 'cmbird_zi_webhook_password', password_hash( 'commercebird-zi-webhook-token', PASSWORD_BCRYPT ) );
			}
			Template::instance();
			// Load the necessary Ajax handlers and templates.
			ZohoInventoryAjax::instance();
			ZohoCRMAjax::instance();
			AcfAjax::instance();
			SettingsAjax::instance();
			ExactOnlineAjax::instance();
			if ( class_exists( 'ACF' ) ) {
				AcfAjax::instance();
				Cmbird_Acf::instance();
			}
		}
		new Cmbird_WC_API();
		new CMBIRD_Purchase_Orders_Automation();
	}

	/**
	 * Cron callback for zoho import sync interval.
	 *
	 * When the WP cron fires this hook we simply forward the request to the
	 * existing `import_simple_items_cron` action.  That action is already
	 * registered in the main plugin bootstrapping script and handles batch
	 * scheduling via Action Scheduler.  Passing along the arguments allows for
	 * backwards compatibility if anybody ever runs the hook manually with
	 * parameters.
	 *
	 * @since 2.7.7
	 * @param mixed ...$args Optional arguments supplied by do_action.
	 * @return void
	 */
	public static function dispatch_import_simple_items( ...$args ) {
		// if the event was fired with explicit arguments we simply forward them.
		// to the existing hook (primarily useful for manual/testing purposes).
		if ( ! empty( $args ) ) {
			do_action( 'import_simple_items_cron', ...$args );
			return;
		}
		$zi_common_class = new \CMBIRD_Common_Functions();
		$zi_common_class->clear_orphan_data();

		// categories are stored as serialized zoho ids; convert them to WC terms.
		$zoho_item_category = get_option( 'cmbird_zoho_item_category' );
		if ( $zoho_item_category ) {
			// convert serialized string to array.
			$categories = maybe_unserialize( $zoho_item_category );
			if ( ! is_array( $categories ) ) {
				return; // invalid format -> nothing to do.
			}
		} else {
			return; // no categories configured -> nothing to do.
		}
		foreach ( $categories as $category_id ) {
			$data = array(
				'page'     => 1,
				'category' => $category_id,
			);
			if ( function_exists( 'as_has_scheduled_action' )
				&& ! as_has_scheduled_action( 'import_simple_items_cron', $data, 'commercebird' )
			) {
				as_schedule_single_action( time(), 'import_simple_items_cron', $data, 'commercebird' );
			}
		}
	}
}
