<?php
// phpcs:ignoreFile WordPress.Files.FileName.InvalidClassFileName
/**
 * Plugin Name: AnyCoin Payment Gateway
 * Plugin URI: https://acceptanycoin.com/plugins/payment-gateway
 * Description: A non-custodial payment processor for WordPress/WooCommerce that allows merchants to accept cryptocurrency with AnyCoin.
 * Version: 1.1.0
 * Author: AnyCoin Team
 * Author URI: https://acceptanycoin.com/about
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html

 * WC requires at least: 3.0.0
 * WC tested up to: 8.5.2
 * Requires PHP: 7.4
 *
 * @package AnyCoin_Payment_Gateway
 *
 * phpcs:disable WordPress.Files.FileName.InvalidClassFileName
 */

/*
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
*/

/**
 * Main plugin loader for AnyCoin Payment Gateway.
 *
 * @package AnyCoin_Payment_Gateway
 */

// phpcs:disable WordPress.Files.FileName.InvalidClassFileName

defined( 'ABSPATH' ) || exit;

// Load Composer autoloader if present (bundled with the plugin release).
if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) {
	require __DIR__ . '/vendor/autoload.php';
}

// Define plugin constants.
define( 'ANYCOIN_PAYMENT_VERSION', '1.1.0' );
define( 'ANYCOIN_PAYMENT_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'ANYCOIN_PAYMENT_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'ANYCOIN_PAYMENT_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

// Set test mode based on settings (will be overridden by settings later).
if ( ! defined( 'ANYCOIN_TEST_MODE' ) ) {
	define( 'ANYCOIN_TEST_MODE', false ); // Default to production mode.
}

// Check if WooCommerce is active.
if ( ! in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ), true ) ) {
	return;
}

/**
 * Main plugin class.
 *
 * @package AnyCoin_Payment_Gateway
 */
final class AnyCoin_Payment_Plugin {

	/**
	 * Plugin instance.
	 *
	 * @var null|AnyCoin_Payment_Plugin
	 */
	private static $instance = null;

	/**
	 * Get plugin instance
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->init_hooks();
	}

	/**
	 * Lightweight debug logger (avoids error_log in production).
	 *
	 * @param string $message Message to log.
	 */
	private function log_debug( $message ) {
		if ( defined( 'WP_DEBUG' ) && WP_DEBUG && function_exists( 'wc_get_logger' ) ) {
			$logger = wc_get_logger();
			$logger->debug( $message, [ 'source' => 'anycoin-plugin' ] );
		}
	}

	/**
	 * Initialize hooks.
	 */
	private function init_hooks() {
		// Plugin lifecycle hooks.
		register_activation_hook( __FILE__, [ $this, 'activate' ] );
		register_deactivation_hook( __FILE__, [ $this, 'deactivate' ] );

		// Core hooks.
		add_action( 'plugins_loaded', [ $this, 'init' ] );
		add_filter( 'woocommerce_payment_gateways', [ $this, 'add_gateway_class' ] );
		add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), [ $this, 'add_settings_link' ] );
		add_filter( 'cron_schedules', [ $this, 'add_cron_schedules' ] );

		// Asset hooks - Load with very late priority to override theme styles.
		// Most themes enqueue at default (10) or 20-50. Use 99 to come last.
		add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_assets' ], 99 );

		// HPOS compatibility.
		add_action( 'before_woocommerce_init', [ $this, 'declare_hpos_compatibility' ] );

		// WooCommerce Blocks compatibility.
		add_action( 'before_woocommerce_init', [ $this, 'declare_blocks_compatibility' ] );
		add_action( 'woocommerce_blocks_loaded', [ $this, 'register_blocks_support' ] );

		// Custom endpoints.
		add_action( 'init', [ $this, 'add_custom_endpoints' ] );
		add_filter( 'query_vars', [ $this, 'add_query_vars' ] );

		// Database maintenance.
		add_action( 'plugins_loaded', [ $this, 'check_database_tables' ] );

		// Cron job hooks - connecting scheduled jobs to their handlers.
		add_action( 'anycoin_monitor_payments', [ $this, 'monitor_payments_cron' ] );
		add_action( 'anycoin_cleanup_expired_payments', [ $this, 'cleanup_expired_payments' ] );
		add_action( 'anycoin_update_payment_statuses', [ $this, 'update_payment_statuses_cron' ] );
		add_action( 'anycoin_check_transactions', [ $this, 'check_transactions_cron' ] ); // Legacy hook for backward compatibility.

		// Removed per-transaction dynamic hooks; monitoring handled via centralized monitor.
	}

	/**
	 * Include required files.
	 * This is called from the init() method so that all files are loaded after WooCommerce.
	 */
	private function include_files() {
		// Constants and factory first.
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-constants.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-factory.php';

		// Utilities.
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-database-manager.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-file-manager.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-cron-manager.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-form-builder.php';

		// Core classes.
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-payment-gateway.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-blocks-support.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-api.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-transaction-handler.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-transaction-monitor.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-database-migration.php';

		// Utilities and handlers.
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-ajax-handlers.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-payment-page-handler.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-qr-generator.php';
		require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-utilities.php';

		// Admin functionality.
		if ( is_admin() ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/admin/class-anycoin-admin.php';
		}
	}

	/**
	 * Initialize components.
	 */
	private function init_components() {
		new AnyCoin_Transaction_Monitor();

		new AnyCoin_Ajax_Handlers();

		new AnyCoin_Payment_Page_Handler();

		if ( is_admin() ) {
			new AnyCoin_Admin();
		}
	}

	/**
	 * Declare HPOS compatibility.
	 */
	public function declare_hpos_compatibility() {
		if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
			\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
		}
	}

	/**
	 * Declare blocks compatibility.
	 */
	public function declare_blocks_compatibility() {
		if ( class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
			\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );
		}
	}

	/**
	 * Register blocks support.
	 */
	public function register_blocks_support() {
		if ( class_exists( 'Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry' ) ) {
			add_action(
				'woocommerce_blocks_payment_method_type_registration',
				function ( Automattic\WooCommerce\Blocks\Payments\PaymentMethodRegistry $payment_method_registry ) {
					$payment_method_registry->register( new AnyCoin_Blocks_Support() );
				}
			);
		}
	}

	/**
	 * Plugin activation.
	 */
	public function activate() {
		if ( ! class_exists( 'AnyCoin_Constants' ) ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/class-anycoin-constants.php';
		}
		if ( ! class_exists( 'AnyCoin_Database_Manager' ) ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-database-manager.php';
		}
		if ( ! class_exists( 'AnyCoin_File_Manager' ) ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-file-manager.php';
		}
		if ( ! class_exists( 'AnyCoin_Cron_Manager' ) ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-cron-manager.php';
		}

		add_filter( 'cron_schedules', [ 'AnyCoin_Cron_Manager', 'add_custom_cron_intervals' ] ); // phpcs:ignore WordPress.WP.CronInterval.ChangeDetected -- Intervals include required 'interval' value.

		AnyCoin_Database_Manager::create_tables();

		AnyCoin_File_Manager::create_directories(); // No-op.
		AnyCoin_File_Manager::create_default_assets(); // No-op.

		AnyCoin_Cron_Manager::init_cron_jobs();

		remove_filter( 'cron_schedules', [ 'AnyCoin_Cron_Manager', 'add_custom_cron_intervals' ] );

		$this->force_database_migration();
	}

	/**
	 * Force database migration to add missing columns.
	 */
	private function force_database_migration() {
		global $wpdb;

		$table_name = $wpdb->prefix . AnyCoin_Constants::DB_TABLE_NAME;

		$table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table_name ) ) ) === $table_name; // phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery,WordPress.DB.DirectDatabaseQuery.NoCaching

		if ( ! $table_exists ) {

			AnyCoin_Database_Manager::create_tables();
			return;
		}

		AnyCoin_Database_Manager::run_table_migrations();
		AnyCoin_Database_Manager::resolve_duplicate_transactions();
	}

	/**
	 * Plugin deactivation.
	 */
	public function deactivate() {

		if ( ! class_exists( 'AnyCoin_Cron_Manager' ) ) {
			require_once ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-cron-manager.php';
		}

		AnyCoin_Cron_Manager::unschedule_all_cron_jobs();
	}

	/**
	 * Initialize plugin.
	 */
	public function init() {

		$this->include_files();

		$this->init_components();
	}

	/**
	 * Add payment gateway class.
	 *
	 * @param array $gateways Gateway class names.
	 * @return array
	 */
	public function add_gateway_class( $gateways ) {
		$gateways[] = 'AnyCoin_Payment_Gateway';
		return $gateways;
	}

	/**
	 * Add settings link.
	 *
	 * @param array $links Action links.
	 * @return array
	 */
	public function add_settings_link( $links ) {
		$settings_link = '<a href="admin.php?page=wc-settings&tab=checkout&section=anycoin_payment">Settings</a>';
		array_unshift( $links, $settings_link );
		return $links;
	}

	/**
	 * Add custom cron schedules.
	 *
	 * @param array $schedules Existing schedules.
	 * @return array
	 */
	public function add_cron_schedules( $schedules ) {
		if ( ! class_exists( 'AnyCoin_Cron_Manager' ) ) {
			$cron_manager_file = ANYCOIN_PAYMENT_PLUGIN_DIR . 'includes/utilities/class-anycoin-cron-manager.php';
			if ( file_exists( $cron_manager_file ) ) {
				require_once $cron_manager_file;
			} else {
				return $schedules;
			}
		}

		return AnyCoin_Cron_Manager::add_custom_cron_intervals( $schedules );
	}

	/**
	 * Enqueue frontend assets.
	 */
	public function enqueue_frontend_assets() {
		$wc_api          = get_query_var( 'wc-api' );
		$wc_api          = $wc_api ? sanitize_key( $wc_api ) : '';
		$is_payment_page = ( $wc_api === 'anycoin_payment_page' );

		if ( $is_payment_page || is_checkout_pay_page() || is_checkout() || is_wc_endpoint_url( 'order-received' ) ) {
			wp_enqueue_style(
				'anycoin-payment-style',
				ANYCOIN_PAYMENT_PLUGIN_URL . 'assets/css/anycoin-payment.css',
				[],
				ANYCOIN_PAYMENT_VERSION,
				'all'
			);

			wp_add_inline_style( 'anycoin-payment-style', '' );

			wp_enqueue_script(
				'anycoin-payment-script',
				ANYCOIN_PAYMENT_PLUGIN_URL . 'assets/js/anycoin-payment.js',
				[ 'jquery' ],
				ANYCOIN_PAYMENT_VERSION,
				true
			);

			wp_localize_script(
				'anycoin-payment-script',
				'anycoin_params',
				[
					'ajax_url'       => admin_url( 'admin-ajax.php' ),
					'nonce'          => wp_create_nonce( 'anycoin_payment_nonce' ),
					'confirmed_text' => 'Payment confirmed! Your order is being processed.',
					'detected_text'  => 'Payment detected! Waiting for confirmations: %s',
					'pending_text'   => 'Waiting for payment...',
					'failed_text'    => 'Payment failed or expired after 20 minutes.',
					'check_text'     => 'Check for Payment',
					'checking_text'  => 'Checking...',
				]
			);
		}
	}

	/**
	 * Add custom endpoints.
	 */
	public function add_custom_endpoints() {
		add_rewrite_endpoint( 'anycoin-payment', EP_ALL );
	}

	/**
	 * Add query vars.
	 *
	 * @param array $vars Query vars.
	 * @return array
	 */
	public function add_query_vars( $vars ) {
		$vars[] = 'order_id';
		return $vars;
	}

	/**
	 * Check database tables.
	 */
	public function check_database_tables() {
		if ( ! is_admin() ) {
			return;
		}

		$check_option = get_option( 'anycoin_db_check', 0 );
		$current_time = time();

		if ( $check_option > ( $current_time - 86400 ) ) {
			return;
		}

		update_option( 'anycoin_db_check', $current_time );
		AnyCoin_Database_Manager::create_tables();
		AnyCoin_Database_Manager::resolve_duplicate_transactions();
	}

	// Removed register_individual_transaction_hooks(); no per-transaction cron wiring needed.

	/**
	 * Cleanup expired payments (cron handler) - marks as failed instead of deleting.
	 */
	public function cleanup_expired_payments() {
		if ( class_exists( 'AnyCoin_Database_Manager' ) ) {
			$cleaned_count = AnyCoin_Database_Manager::delete_expired_payments();
			if ( $cleaned_count > 0 ) {
				$this->log_debug( "AnyCoin: Marked {$cleaned_count} expired payments as failed" );
			}
		}
	}

	/**
	 * Monitor payments cron handler.
	 */
	public function monitor_payments_cron() {
		if ( class_exists( 'AnyCoin_Transaction_Monitor' ) ) {
			$monitor = new AnyCoin_Transaction_Monitor();
			$monitor->check_transactions();
		}
	}

	/**
	 * Update payment statuses cron handler.
	 */
	public function update_payment_statuses_cron() {
		if ( class_exists( 'AnyCoin_Utilities' ) ) {
			$updated_count = AnyCoin_Utilities::update_all_order_statuses();
			if ( $updated_count > 0 ) {
				$this->log_debug( "AnyCoin: Updated {$updated_count} payment statuses" );
			}
		}
	}

	/**
	 * Check transactions cron handler (legacy - for backward compatibility).
	 */
	public function check_transactions_cron() {
		$this->monitor_payments_cron();
	}
}

AnyCoin_Payment_Plugin::get_instance();
