<?php
/**
 * Main plugin class — singleton.
 *
 * @package GoValid_QR
 */

defined( 'ABSPATH' ) || exit;

class GoValid_QR {

	/** @var self|null */
	private static $instance = null;

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

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

	/**
	 * Load plugin text domain.
	 *
	 * Since WordPress 4.6, translations hosted on WordPress.org are loaded
	 * automatically. This is kept only as a fallback for custom translations
	 * bundled in the plugin's /languages directory.
	 */
	private function load_textdomain(): void {
		// WordPress.org handles translations automatically since WP 4.6.
		// No manual load_plugin_textdomain() call needed.
	}

	/**
	 * Register all hooks.
	 */
	private function register_hooks(): void {
		// Custom verification page (/v/{token}).
		add_filter( 'query_vars', array( $this, 'add_verify_query_var' ) );
		add_action( 'init', array( $this, 'register_verify_rewrite' ) );
		add_action( 'init', array( $this, 'maybe_flush_rewrite_rules' ) );

		// Admin hooks.
		if ( is_admin() ) {
			$admin = new GoValid_Admin();
			$admin->register();

			$settings = new GoValid_Admin_Settings();
			$settings->register();

			$generator = new GoValid_Admin_Generator();
			$generator->register();

			$dashboard = new GoValid_Admin_Dashboard();
			$dashboard->register();

			$admin_forms = new GoValid_Admin_Forms();
			$admin_forms->register();
		}

		// REST API.
		$rest = new GoValid_Rest_Controller();
		$rest->register();

		$link_rest = new GoValid_Link_Rest_Controller();
		$link_rest->register();

		$form_rest = new GoValid_Form_Rest_Controller();
		$form_rest->register();

		// Gutenberg blocks.
		$blocks = new GoValid_Blocks();
		$blocks->register();

		// Shortcodes.
		$shortcodes = new GoValid_Shortcodes();
		$shortcodes->register();

		// Form shortcode.
		$form_shortcode = new GoValid_Form_Shortcode();
		$form_shortcode->register();

		// Verify widget (shortcode + floating FAB).
		$verify = new GoValid_Verify_Shortcode();
		$verify->register();

		// Verification page shortcodes.
		$verify_page = new GoValid_Verify_Page_Shortcode();
		$verify_page->register();

		// Cache cleanup cron.
		$cache = GoValid_Cache::get_instance();
		$cache->register();
	}

	/**
	 * Get the GoValid base URL.
	 */
	public static function get_base_url(): string {
		$url = get_option( 'govalid_qr_base_url', GOVALID_QR_DEFAULT_BASE_URL );
		return rtrim( $url, '/' );
	}

	/**
	 * Check if the plugin is connected to GoValid.
	 */
	public static function is_connected(): bool {
		$token_manager = new GoValid_Token_Manager();
		return $token_manager->has_tokens();
	}

	/**
	 * Register rewrite rule for /v/{token}.
	 *
	 * Routes to the designated verification page so its shortcodes
	 * can read the token via get_query_var('govalid_verify_token').
	 */
	public function register_verify_rewrite(): void {
		$page_id = (int) get_option( 'govalid_qr_verify_page_id', 0 );
		if ( $page_id && 'publish' === get_post_status( $page_id ) ) {
			add_rewrite_rule(
				'^v/(.+)/?$',
				'index.php?page_id=' . $page_id . '&govalid_verify_token=$matches[1]',
				'top'
			);
		}
	}

	/**
	 * Add custom query var for verify token.
	 *
	 * @param array $vars Existing query vars.
	 * @return array
	 */
	public function add_verify_query_var( array $vars ): array {
		$vars[] = 'govalid_verify_token';
		return $vars;
	}

	/**
	 * Create the verification page automatically.
	 *
	 * @return int|WP_Error Page ID on success, WP_Error on failure.
	 */
	public static function create_verify_page() {
		$existing = get_option( 'govalid_qr_verify_page_id', 0 );
		if ( $existing && 'publish' === get_post_status( $existing ) ) {
			return (int) $existing;
		}

		$page_id = wp_insert_post( array(
			'post_title'   => __( 'QR Code Verification', 'govalid-qr-validator' ),
			'post_name'    => 'govalid-verify',
			'post_content' => '[govalid_verify_result]',
			'post_status'  => 'publish',
			'post_type'    => 'page',
			'meta_input'   => array(
				'_govalid_verify_page' => '1',
			),
		) );

		if ( ! is_wp_error( $page_id ) ) {
			update_option( 'govalid_qr_verify_page_id', $page_id );
			update_option( 'govalid_qr_flush_rewrite', '1' );
		}

		return $page_id;
	}

	/**
	 * Flush rewrite rules after a setting toggle or plugin update.
	 */
	public function maybe_flush_rewrite_rules(): void {
		$needs_flush = false;

		// Flush on setting change.
		if ( get_option( 'govalid_qr_flush_rewrite', '0' ) === '1' ) {
			delete_option( 'govalid_qr_flush_rewrite' );
			$needs_flush = true;
		}

		// Flush on version change (plugin update).
		if ( get_option( 'govalid_qr_version', '' ) !== GOVALID_QR_VERSION ) {
			update_option( 'govalid_qr_version', GOVALID_QR_VERSION );
			$needs_flush = true;
		}

		if ( $needs_flush ) {
			flush_rewrite_rules( false );
		}
	}
}
