<?php
/**
 * Admin screens and assets.
 *
 * @package CertaCart_EU_Product_Readiness
 */

namespace CertaCart\EU_Product_Readiness;

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

final class Admin {
	private static ?Admin $instance = null;
	private const APP_PAGE_SLUGS = array(
		'ccpr-readiness',
		'ccpr-tasks',
		'ccpr-history',
		'ccpr-settings',
		'ccpr-pro-bulk-tools',
		'ccpr-pro-settings',
	);

	public static function instance(): Admin {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	public function register(): void {
		add_action( 'admin_menu', array( $this, 'menu' ), 60 );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_focus_shell' ), 20 );
		add_action( 'in_admin_header', array( $this, 'render_profile_navigation' ) );
		add_action( 'admin_init', array( $this, 'maybe_redirect_after_activation' ) );
		add_action( 'admin_post_ccpr_export_scan', array( Exporter::class, 'handle' ) ); // ccpr-security: delegated-handler
		add_action( 'admin_post_ccpr_quick_start', array( $this, 'quick_start' ) );
		add_filter( 'plugin_action_links_' . CCPR_BASENAME, array( $this, 'action_links' ) );
		add_filter( 'admin_body_class', array( $this, 'focus_body_class' ) );
	}

	public function menu(): void {
		add_submenu_page(
			'woocommerce',
			__( 'CertaCart', 'certacart-eu-product-readiness' ),
			__( 'CertaCart', 'certacart-eu-product-readiness' ),
			'manage_woocommerce',
			'ccpr-readiness',
			array( $this, 'dashboard' )
		);
		add_submenu_page(
			null,
			__( 'CertaCart Tasks', 'certacart-eu-product-readiness' ),
			__( 'CertaCart Tasks', 'certacart-eu-product-readiness' ),
			'manage_woocommerce',
			'ccpr-tasks',
			array( $this, 'tasks' )
		);
		add_submenu_page(
			null,
			__( 'CertaCart History', 'certacart-eu-product-readiness' ),
			__( 'CertaCart History', 'certacart-eu-product-readiness' ),
			'manage_woocommerce',
			'ccpr-history',
			array( $this, 'history' )
		);
		add_submenu_page(
			null,
			__( 'CertaCart Settings', 'certacart-eu-product-readiness' ),
			__( 'CertaCart Settings', 'certacart-eu-product-readiness' ),
			'manage_woocommerce',
			'ccpr-settings',
			array( $this, 'settings' )
		);
	}

	/**
	 * Load the app-shell styles on CertaCart-owned screens that do not use our page callbacks.
	 */
	public function enqueue_focus_shell( string $hook ): void {
		if ( ! $this->is_app_screen( $hook ) ) {
			return;
		}

		wp_enqueue_style( 'ccpr-admin', CCPR_URL . 'assets/css/admin.css', array(), CCPR_VERSION );
	}

	/**
	 * Add the focus-mode marker without affecting any other WordPress screen.
	 */
	public function focus_body_class( string $classes ): string {
		return $this->is_app_screen() ? $classes . ' ccpr-focus-mode' : $classes;
	}

	/**
	 * Give the Pro profile list/editor the same in-app navigation as CertaCart pages.
	 */
	public function render_profile_navigation(): void {
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( ! $screen || 'ccpr_profile' !== (string) $screen->post_type ) {
			return;
		}

		$ccpr_current_page = 'profiles';
		require CCPR_PATH . 'templates/admin-navigation.php';
	}

	/**
	 * Limit the focused shell to CertaCart's own routes and Pro profile screens.
	 */
	private function is_app_screen( string $hook = '' ): bool {
		$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen routing.
		if ( in_array( $page, self::APP_PAGE_SLUGS, true ) ) {
			return true;
		}

		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		if ( $screen && 'ccpr_profile' === (string) $screen->post_type ) {
			return true;
		}

		return false !== strpos( $hook, 'ccpr-' );
	}

	public function enqueue( string $hook ): void {
		$is_ccpr    = false !== strpos( $hook, 'ccpr-' );
		$screen     = get_current_screen();
		$is_product = in_array( $hook, array( 'post.php', 'post-new.php' ), true ) && $screen && 'product' === $screen->post_type;
		if ( ! $is_ccpr && ! $is_product ) {
			return;
		}

		wp_enqueue_style( 'ccpr-admin', CCPR_URL . 'assets/css/admin.css', array(), CCPR_VERSION );
		if ( ! $is_ccpr ) {
			if ( $is_product ) {
				wp_enqueue_script( 'ccpr-product-admin', CCPR_URL . 'assets/js/product-admin.js', array( 'wc-admin-product-meta-boxes' ), CCPR_VERSION, true );
			}
			return;
		}

		wp_enqueue_media();
		wp_enqueue_script( 'ccpr-admin', CCPR_URL . 'assets/js/admin.js', array(), CCPR_VERSION, true );
		$repository = new Scan_Repository();
		$latest     = $this->scan_from_request( $repository );
		$auto_start_scope = Settings::sanitize_scan_scope( get_transient( 'ccpr_auto_start_' . get_current_user_id() ) );
		$auto_start       = '' !== $auto_start_scope;
		$selected_task = isset( $_GET['task'] ) ? sanitize_key( wp_unslash( $_GET['task'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report filter.
		$selected_rules = $selected_task && 'all' !== $selected_task ? ( new Task_Aggregator() )->rules_for_task( $selected_task ) : array();
		wp_localize_script(
			'ccpr-admin',
			'ccprAdmin',
			array(
				'restUrl'      => esc_url_raw( rest_url( 'certacart/v1/' ) ),
				'nonce'        => wp_create_nonce( 'wp_rest' ),
				'latestScanId' => $latest ? (int) $latest['id'] : 0,
				'page'         => isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '', // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only screen state.
				'selectedTask' => $selected_task,
				'selectedTaskRules' => $selected_rules,
				'autoStart'    => $auto_start,
				'autoStartScope' => $auto_start_scope,
				'exportBase'   => admin_url( 'admin-post.php?action=ccpr_export_scan' ),
				'exportNonce'  => wp_create_nonce( 'ccpr_export_scan' ),
				'tasksUrl'     => admin_url( 'admin.php?page=ccpr-tasks' ),
				'strings'      => array(
					'starting'             => __( 'Starting scan…', 'certacart-eu-product-readiness' ),
					'running'              => __( 'Scanning your store…', 'certacart-eu-product-readiness' ),
					'complete'             => __( 'Scan complete.', 'certacart-eu-product-readiness' ),
					'failed'               => __( 'The scan was interrupted.', 'certacart-eu-product-readiness' ),
					'cancelled'            => __( 'Scan stopped.', 'certacart-eu-product-readiness' ),
					'cancelling'           => __( 'Stopping scan…', 'certacart-eu-product-readiness' ),
					'noResults'            => __( 'No matching products found.', 'certacart-eu-product-readiness' ),
					'edit'                 => __( 'Edit product', 'certacart-eu-product-readiness' ),
					'view'                 => __( 'View product', 'certacart-eu-product-readiness' ),
					'inScope'              => __( 'in scope', 'certacart-eu-product-readiness' ),
					'notApplicable'        => __( 'N/A', 'certacart-eu-product-readiness' ),
					'products'             => __( 'products', 'certacart-eu-product-readiness' ),
					'affected'             => __( 'products affected', 'certacart-eu-product-readiness' ),
					'allClear'             => __( 'No supported information gaps found', 'certacart-eu-product-readiness' ),
					/* translators: %s: product information readiness percentage. */
					'homeScore'            => __( 'EU product information readiness: %s%', 'certacart-eu-product-readiness' ),
					'homeIssuesSubtitle'   => __( 'Start with the task that moves the most products forward.', 'certacart-eu-product-readiness' ),
					'allClearSubtitle'     => __( 'All supported product information checks passed in the latest scan.', 'certacart-eu-product-readiness' ),
					'chooseScopeTitle'     => __( 'Choose which products you sell to the EU.', 'certacart-eu-product-readiness' ),
					'chooseScopeSubtitle'  => __( 'No products were scored because EU sales scope is not set.', 'certacart-eu-product-readiness' ),
					'reviewReadyTitle'     => __( 'Your product information action plan is ready.', 'certacart-eu-product-readiness' ),
					'reviewReadySubtitle'  => __( 'Review the ranked tasks now. Confirm EU sales scope when you want a readiness score.', 'certacart-eu-product-readiness' ),
					'noProductsTitle'      => __( 'No published products found in this scan.', 'certacart-eu-product-readiness' ),
					'noProductsSubtitle'   => __( 'Add or publish a product to build your product information action plan.', 'certacart-eu-product-readiness' ),
					'highConfidence'      => __( 'High detection confidence', 'certacart-eu-product-readiness' ),
					'reviewNeeded'         => __( 'Merchant review needed', 'certacart-eu-product-readiness' ),
					/* translators: 1: processed product count, 2: total product count. */
					'productsChecked'      => __( '%1$s of %2$s products checked', 'certacart-eu-product-readiness' ),
					'productDataUnchanged' => __( 'Your product data was not changed.', 'certacart-eu-product-readiness' ),
					'requestFailed'        => __( 'Request failed', 'certacart-eu-product-readiness' ),
					'ready'                => __( 'Ready', 'certacart-eu-product-readiness' ),
					'preparing'            => __( 'Preparing your catalog…', 'certacart-eu-product-readiness' ),
				),
			)
		);
	}

	public function dashboard(): void {
		$this->require_capability();
		$repository    = new Scan_Repository();
		$latest        = $repository->latest();
		$all_tasks     = $latest && 'completed' === $latest['status'] ? ( new Task_Aggregator() )->for_scan( (int) $latest['id'] ) : array();
		$tasks         = array_slice( $all_tasks, 0, 3 );
		$task_count    = count( $all_tasks );
		$high_confidence_task_count = count(
			array_filter(
				$all_tasks,
				static fn( array $task ): bool => 'high' === ( $task['confidence'] ?? '' )
			)
		);
		$affected_products = $latest && 'completed' === $latest['status'] ? $repository->affected_product_count( (int) $latest['id'] ) : 0;
		$auto_start_scope  = Settings::sanitize_scan_scope( get_transient( 'ccpr_auto_start_' . get_current_user_id() ) );
		$needs_quick_start = 'review' === Settings::get( 'default_targets_eu', 'review' ) && ! $latest && '' === $auto_start_scope;
		if ( '' !== $auto_start_scope ) {
			delete_transient( 'ccpr_auto_start_' . get_current_user_id() );
		}
		$notice_status = $this->global_notice_status();
		$export_url    = '';
		if ( $latest ) {
			$export_url = wp_nonce_url(
				admin_url( 'admin-post.php?action=ccpr_export_scan&scan_id=' . absint( $latest['id'] ) ),
				'ccpr_export_scan'
			);
		}
		require CCPR_PATH . 'templates/admin-dashboard.php';
	}

	public function tasks(): void {
		$this->require_capability();
		$repository    = new Scan_Repository();
		$scan          = $this->scan_from_request( $repository );
		$tasks         = $scan && 'completed' === $scan['status'] ? ( new Task_Aggregator() )->for_scan( (int) $scan['id'] ) : array();
		$selected_task_key = isset( $_GET['task'] ) ? sanitize_key( wp_unslash( $_GET['task'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report filter.
		if ( '' === $selected_task_key && $tasks ) {
			$selected_task_key = (string) $tasks[0]['rule'];
		}
		$selected_task = null;
		foreach ( $tasks as $task ) {
			if ( $selected_task_key === $task['rule'] ) {
				$selected_task = $task;
				break;
			}
		}
		$export_url = $scan ? wp_nonce_url( admin_url( 'admin-post.php?action=ccpr_export_scan&scan_id=' . absint( $scan['id'] ) ), 'ccpr_export_scan' ) : '';
		require CCPR_PATH . 'templates/admin-tasks.php';
	}

	public function history(): void {
		$this->require_capability();
		$scans = ( new Scan_Repository() )->recent( 50 );
		require CCPR_PATH . 'templates/admin-history.php';
	}

	public function settings(): void {
		$this->require_capability();
		$settings = Settings::all();
		require CCPR_PATH . 'templates/admin-settings.php';
	}

	private function scan_from_request( Scan_Repository $repository ): ?array {
		$scan_id = isset( $_GET['scan_id'] ) ? absint( wp_unslash( $_GET['scan_id'] ) ) : 0; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only report selection.
		if ( $scan_id ) {
			$scan = $repository->get( $scan_id );
			if ( $scan ) {
				return $scan;
			}
		}
		return $repository->latest();
	}

	public function quick_start(): void {
		$this->require_capability();
		check_admin_referer( 'ccpr_quick_start' );
		$scope = Settings::sanitize_scan_scope( sanitize_key( wp_unslash( $_POST['ccpr_scan_scope'] ?? '' ) ) );
		if ( '' === $scope ) {
			wp_die( esc_html__( 'Choose the EU sales scope for this scan.', 'certacart-eu-product-readiness' ), '', array( 'response' => 400 ) );
		}
		set_transient( 'ccpr_auto_start_' . get_current_user_id(), $scope, 60 );
		wp_safe_redirect( admin_url( 'admin.php?page=ccpr-readiness' ) );
		exit;
	}

	public function maybe_redirect_after_activation(): void {
		if ( ! get_transient( 'ccpr_activation_redirect' ) ) {
			return;
		}
		delete_transient( 'ccpr_activation_redirect' );
		if ( wp_doing_ajax() || is_network_admin() || ! current_user_can( 'manage_woocommerce' ) ) {
			return;
		}
		wp_safe_redirect( admin_url( 'admin.php?page=ccpr-readiness' ) );
		exit;
	}

	public function action_links( array $links ): array {
		$links[] = '<a href="' . esc_url( admin_url( 'admin.php?page=ccpr-readiness' ) ) . '">' . esc_html__( 'Scan', 'certacart-eu-product-readiness' ) . '</a>';
		$links[] = '<a href="' . esc_url( admin_url( 'admin.php?page=ccpr-settings' ) ) . '">' . esc_html__( 'Settings', 'certacart-eu-product-readiness' ) . '</a>';
		$upgrade_url = Commercial::upgrade_url();
		if ( $upgrade_url ) {
			$links[] = '<a href="' . esc_url( $upgrade_url ) . '"><strong>' . esc_html__( 'Upgrade', 'certacart-eu-product-readiness' ) . '</strong></a>';
		}
		return $links;
	}

	private function global_notice_status(): array {
		$settings  = Settings::all();
		$scope     = $settings['notice_scope'] ?? 'review';
		$effective = strtotime( '2026-09-27 00:00:00 UTC' );
		$now       = (int) current_time( 'timestamp', true );

		if ( 'not_applicable' === $scope ) {
			return array(
				'type'    => 'info',
				'message' => __( 'The guarantee-notice helper is marked not applicable after manual review. Keep the basis for that decision outside this plugin.', 'certacart-eu-product-readiness' ),
			);
		}
		if ( 'configured' === $scope && 'yes' === ( $settings['notice_enabled'] ?? 'no' ) && ! empty( $settings['notice_attachment_id'] ) ) {
			return array(
				'type'    => 'success',
				'message' => __( 'A locally hosted guarantee-notice asset is configured. Manually confirm the official language, artwork, placement, and legal applicability.', 'certacart-eu-product-readiness' ),
			);
		}
		if ( 'configured' === $scope ) {
			return array(
				'type'    => 'warning',
				'message' => __( 'The guarantee notice is marked configured, but display is disabled or no local artwork is selected.', 'certacart-eu-product-readiness' ),
			);
		}
		if ( $now < $effective ) {
			return array(
				'type'    => 'info',
				'message' => __( 'Review the harmonised legal-guarantee notice before 27 September 2026 and record whether it applies to this storefront.', 'certacart-eu-product-readiness' ),
			);
		}
		return array(
			'type'    => 'warning',
			'message' => __( 'Guarantee-notice applicability has not been recorded. Review the official European Commission materials for this point of sale.', 'certacart-eu-product-readiness' ),
		);
	}

	private function require_capability(): void {
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'certacart-eu-product-readiness' ) );
		}
	}
}
