<?php
/**
 * Plugin Activator
 *
 * Handles all plugin activation tasks including:
 * - Database table creation
 * - Default options setup
 * - Version tracking
 * - Migration from older versions
 *
 * @package FormConnector
 * @subpackage Setup
 */

declare(strict_types=1);

namespace FormConnector\Core\Setup;

defined('ABSPATH') || exit;

/**
 * Activator class
 */
class Activator {

	/**
	 * Plugin version option key
	 */
	private const VERSION_OPTION = 'fc_plugin_version';

	/**
	 * Database version option key
	 */
	private const DB_VERSION_OPTION = 'fc_db_version';

	/**
	 * Current database schema version
	 */
	private const DB_VERSION = '1.0.0';

	/**
	 * Run activation tasks
	 *
	 * Called when the plugin is activated.
	 *
	 * @return void
	 */
	public static function activate(): void {
		self::check_requirements();
		self::create_tables();
		self::set_default_options();
		self::update_version();
		self::schedule_events();
		self::clear_caches();

		// Log activation for debugging
		if (defined('WP_DEBUG') && WP_DEBUG) {
			error_log('[FormConnector] Plugin activated. Version: ' . FC_VERSION);
		}
	}

	/**
	 * Check system requirements
	 *
	 * @return void
	 * @throws \Exception If requirements are not met
	 */
	private static function check_requirements(): void {
		// Check PHP version
		if (version_compare(PHP_VERSION, '8.0', '<')) {
			deactivate_plugins(FC_PLUGIN_BASENAME);
			wp_die(
				esc_html__('Form Connector requires PHP 8.0 or higher.', 'form-connector'),
				esc_html__('Plugin Activation Error', 'form-connector'),
				['back_link' => true]
			);
		}

		// Check WordPress version
		global $wp_version;
		if (version_compare($wp_version, '6.0', '<')) {
			deactivate_plugins(FC_PLUGIN_BASENAME);
			wp_die(
				esc_html__('Form Connector requires WordPress 6.0 or higher.', 'form-connector'),
				esc_html__('Plugin Activation Error', 'form-connector'),
				['back_link' => true]
			);
		}
	}

	/**
	 * Create database tables
	 *
	 * @return void
	 */
	private static function create_tables(): void {
		// Create submissions log table
		\FormConnector\Features\Logs\Logs::get_instance()->create_table();

		// Create retry queue table
		\FormConnector\Features\Retry\RetryQueue::get_instance()->create_table();

		// Create attribution table
		\FormConnector\Features\Attribution\AttributionTracker::get_instance()->create_table();
	}

	/**
	 * Set default options if they don't exist
	 *
	 * @return void
	 */
	private static function set_default_options(): void {
		// Plugin settings defaults
		$default_settings = [
			'utm_tracking_enabled'  => true,
			'utm_cookie_duration'   => 30,
			'logging_enabled'       => true,
			'log_retention_days'    => 0,
		];

		// Only add if option doesn't exist
		if (get_option('fc_settings') === false) {
			add_option('fc_settings', $default_settings);
		}

		// Initialize empty mappings if not exists
		if (get_option('fc_form_mappings') === false) {
			add_option('fc_form_mappings', []);
		}

		// Initialize empty conditional mappings if not exists
		if (get_option('fc_conditional_mappings') === false) {
			add_option('fc_conditional_mappings', []);
		}
	}

	/**
	 * Update version tracking
	 *
	 * @return void
	 */
	private static function update_version(): void {
		$previous_version = get_option(self::VERSION_OPTION, '0.0.0');

		// Run migrations if upgrading
		if (version_compare($previous_version, FC_VERSION, '<')) {
			self::run_migrations($previous_version);
		}

		// Update stored version
		update_option(self::VERSION_OPTION, FC_VERSION);
		update_option(self::DB_VERSION_OPTION, self::DB_VERSION);
		update_option('fc_log_table_version', FC_VERSION);
	}

	/**
	 * Run version migrations
	 *
	 * @param string $from_version Version upgrading from
	 * @return void
	 */
	private static function run_migrations(string $from_version): void {
		// Migration from v2.x to v3.x
		if (version_compare($from_version, '3.0.0', '<')) {
			self::migrate_from_v2();
		}

		// Add location_id index if missing (v3.0.1+)
		self::ensure_location_id_index();

		// Add UTM tracking columns (v3.0.0+)
		self::ensure_utm_columns();
	}

	/**
	 * Ensure UTM tracking columns exist on the logs table
	 *
	 * @return void
	 */
	private static function ensure_utm_columns(): void {
		global $wpdb;

		$table_name = $wpdb->prefix . 'fc_submissions_log';

		// Check if table exists
		if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) !== $table_name) {
			return;
		}

		// Columns to add if missing
		$columns = [
			'utm_term'       => "ALTER TABLE {$table_name} ADD COLUMN utm_term varchar(255) DEFAULT '' NOT NULL AFTER utm_campaign",
			'utm_content'    => "ALTER TABLE {$table_name} ADD COLUMN utm_content varchar(255) DEFAULT '' NOT NULL AFTER utm_term",
			'utm_id'         => "ALTER TABLE {$table_name} ADD COLUMN utm_id varchar(255) DEFAULT '' NOT NULL AFTER utm_content",
			'landing_page'   => "ALTER TABLE {$table_name} ADD COLUMN landing_page varchar(500) DEFAULT '' NOT NULL AFTER utm_id",
			'referrer_other' => "ALTER TABLE {$table_name} ADD COLUMN referrer_other varchar(500) DEFAULT '' NOT NULL AFTER landing_page",
		];

		foreach ($columns as $column_name => $alter_sql) {
			// Check if column exists
			$column_exists = $wpdb->get_var($wpdb->prepare(
				"SELECT COUNT(*) FROM INFORMATION_SCHEMA.COLUMNS 
				 WHERE table_schema = %s AND table_name = %s AND column_name = %s",
				DB_NAME,
				$table_name,
				$column_name
			));

			if (!$column_exists) {
				// phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared -- SQL is built from known safe values
				$wpdb->query($alter_sql);

				if (defined('WP_DEBUG') && WP_DEBUG) {
					error_log("[FormConnector] Added {$column_name} column to logs table");
				}
			}
		}
	}

	/**
	 * Ensure the location_id index exists on the logs table
	 *
	 * @return void
	 */
	private static function ensure_location_id_index(): void {
		global $wpdb;

		$table_name = $wpdb->prefix . 'fc_submissions_log';

		// Check if table exists
		if ($wpdb->get_var($wpdb->prepare("SHOW TABLES LIKE %s", $table_name)) !== $table_name) {
			return;
		}

		// Check if index already exists
		$index_exists = $wpdb->get_var($wpdb->prepare(
			"SELECT COUNT(*) FROM INFORMATION_SCHEMA.STATISTICS 
			 WHERE table_schema = %s AND table_name = %s AND index_name = 'location_id'",
			DB_NAME,
			$table_name
		));

		if (!$index_exists) {
			// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- table name is safe
			$wpdb->query("ALTER TABLE {$table_name} ADD INDEX location_id (location_id)");

			if (defined('WP_DEBUG') && WP_DEBUG) {
				error_log('[FormConnector] Added location_id index to logs table');
			}
		}
	}

	/**
	 * Migrate data from v2.x
	 *
	 * @return void
	 */
	private static function migrate_from_v2(): void {
		// Check for old plugin options and migrate if present
		$old_options = [
			'cfc_sales_channel_id' => 'fc_carehq_sales_channel_id',
			'cfc_api_key' => 'fc_carehq_api_key',
			'cfc_api_secret' => 'fc_carehq_api_secret',
			'cfc_account_id' => 'fc_carehq_account_id',
		];

		foreach ($old_options as $old_key => $new_key) {
			$old_value = get_option($old_key);
			if ($old_value !== false && get_option($new_key) === false) {
				update_option($new_key, $old_value);
				// Keep old option for backward compatibility, don't delete
			}
		}

		if (defined('WP_DEBUG') && WP_DEBUG) {
			error_log('[FormConnector] Migrated settings from v2.x to v3.x');
		}
	}

	/**
	 * Schedule cron events
	 *
	 * @return void
	 */
	private static function schedule_events(): void {
		// Schedule daily license check if not already scheduled
		if (!wp_next_scheduled('fc_daily_license_check')) {
			wp_schedule_event(time(), 'daily', 'fc_daily_license_check');
		}

		// Schedule log cleanup if not already scheduled
		if (!wp_next_scheduled('fc_daily_log_cleanup')) {
			wp_schedule_event(time(), 'daily', 'fc_daily_log_cleanup');
		}

		// Schedule retry queue processing
		\FormConnector\Features\Retry\RetryQueue::get_instance()->schedule_cron();

		// Schedule recurring CareHQ health ping
		\FormConnector\Integration\Health\HealthPing::schedule_cron();
	}

	/**
	 * Clear all plugin caches
	 *
	 * @return void
	 */
	private static function clear_caches(): void {
		// Clear all plugin transients
		$transients = [
			'fc_license_cache',
			'fc_license_validated',
			'fc_carehq_connection_cache',
			'fc_carehq_locations',
			'fc_carehq_sales_channels_*', // Wildcard - handled specially
			'fc_homes_cache',
		];

		foreach ($transients as $transient) {
			if (strpos($transient, '*') === false) {
				delete_transient($transient);
			}
		}

		// Clear object cache if available
		if (function_exists('wp_cache_flush_group')) {
			wp_cache_flush_group('formconnector');
		}
	}

	/**
	 * Run upgrade check on admin_init
	 * 
	 * This ensures upgrades happen even if activation hook didn't fire
	 * (e.g., manual file updates via FTP)
	 *
	 * @return void
	 */
	public static function maybe_upgrade(): void {
		$stored_version = get_option(self::VERSION_OPTION, '0.0.0');

		if (version_compare($stored_version, FC_VERSION, '<')) {
			self::activate();
		}
	}
}
