<?php
/**
 * Administration réseau (multisite).
 *
 * @package CVS
 * @license GPL-2.0-or-later
 */

defined( 'ABSPATH' ) || exit;

class CVS_Network_Admin {

	const PAGE_SLUG = 'core-version-switcher-by-volade-network';

	/** @var CVS_Plugin */
	private $plugin;

	public function __construct( CVS_Plugin $plugin ) {
		$this->plugin = $plugin;

		add_action( 'network_admin_menu', array( $this, 'register_menu' ) );
		add_action( 'network_admin_edit_cvs_save_network_settings', array( $this, 'handle_save' ) );
		add_action( 'network_admin_edit_cvs_apply_preset_network', array( $this, 'handle_apply_preset' ) );
		add_action( 'network_admin_edit_cvs_clear_target_network', array( $this, 'handle_clear_target' ) );
		add_action( 'network_admin_edit_cvs_clear_updater_lock_network', array( $this, 'handle_clear_lock' ) );
		add_action( 'network_admin_edit_cvs_refresh_releases_network', array( $this, 'handle_refresh_releases' ) );
		add_action( 'network_admin_edit_cvs_export_network', array( $this, 'handle_export' ) );
		add_action( 'network_admin_edit_cvs_import_network', array( $this, 'handle_import' ) );
	}

	public function register_menu() {
		add_submenu_page(
			'settings.php',
			__( 'Core Version Switcher by Volade', 'core-version-switcher-by-volade' ),
			__( 'Core Version', 'core-version-switcher-by-volade' ),
			'manage_network_options',
			self::PAGE_SLUG,
			array( $this, 'render_page' )
		);
	}

	public static function settings_url( $extra = array() ) {
		$args = array_merge( array( 'page' => self::PAGE_SLUG ), $extra );
		return network_admin_url( 'settings.php?' . http_build_query( $args ) );
	}

	public function handle_save() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_save_network_settings' );
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in CVS_Settings::sanitize().
		$input = wp_unslash( $_POST['cvs'] ?? array() );
		if ( ! is_array( $input ) ) {
			$input = array();
		}

		$old_target = CVS_Settings::sanitize_version( $this->plugin->settings->all_network()['target_version'] ?? '' );
		$new_target = CVS_Settings::sanitize_version( $input['target_version'] ?? '' );

		$valid = $this->plugin->settings->validate_target( $new_target, $input );
		if ( is_wp_error( $valid ) ) {
			wp_safe_redirect( add_query_arg( 'cvs_error', rawurlencode( $valid->get_error_message() ), self::settings_url() ) );
			exit;
		}

		if ( $new_target && $new_target !== $old_target ) {
			$this->plugin->settings->remember_previous_version();
			$this->plugin->settings->mark_pin_set();
		}

		$this->plugin->settings->save( $input, 'network' );

		wp_safe_redirect( add_query_arg( 'updated', '1', self::settings_url() ) );
		exit;
	}

	public function handle_apply_preset() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_apply_preset' );
		$slug    = sanitize_key( wp_unslash( $_POST['cvs_preset'] ?? '' ) );
		$version = CVS_Presets::resolve( $slug, $this->plugin );

		if ( is_wp_error( $version ) ) {
			wp_safe_redirect( add_query_arg( 'preset_error', '1', self::settings_url() ) );
			exit;
		}

		$valid = $this->plugin->settings->validate_target( $version );
		if ( is_wp_error( $valid ) ) {
			wp_safe_redirect( add_query_arg( 'cvs_error', rawurlencode( $valid->get_error_message() ), self::settings_url() ) );
			exit;
		}

		$this->plugin->settings->remember_previous_version();
		$this->plugin->settings->mark_pin_set();
		$settings                   = $this->plugin->settings->all_network();
		$settings['target_version'] = $version;
		$this->plugin->settings->save( $settings, 'network' );

		wp_safe_redirect( add_query_arg( 'preset_applied', '1', self::settings_url() ) );
		exit;
	}

	public function handle_clear_target() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_clear_target' );
		$this->plugin->settings->clear_target( 'network' );
		wp_safe_redirect( add_query_arg( 'cleared', '1', self::settings_url() ) );
		exit;
	}

	public function handle_clear_lock() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_clear_updater_lock' );
		delete_option( 'core_updater.lock' );
		wp_safe_redirect( add_query_arg( 'lock_cleared', '1', self::settings_url() ) );
		exit;
	}

	public function handle_refresh_releases() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_refresh_releases' );
		CVS_Releases::fetch_stable_map( true );
		wp_safe_redirect( add_query_arg( 'releases_refreshed', '1', self::settings_url() ) );
		exit;
	}

	public function handle_export() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_export_settings' );

		$json = $this->plugin->settings->export_json( 'network' );
		$name = 'cvs-network-' . gmdate( 'Y-m-d' ) . '.json';

		nocache_headers();
		header( 'Content-Type: application/json; charset=utf-8' );
		header( 'Content-Disposition: attachment; filename="' . $name . '"' );
		echo $json; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
		exit;
	}

	public function handle_import() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		check_admin_referer( 'cvs_import_settings' );

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated with is_uploaded_file().
		$tmp_name = isset( $_FILES['cvs_import_file']['tmp_name'] ) ? $_FILES['cvs_import_file']['tmp_name'] : '';
		if ( empty( $tmp_name ) || ! is_uploaded_file( $tmp_name ) ) {
			wp_safe_redirect( add_query_arg( 'import_error', '1', self::settings_url() ) );
			exit;
		}

		$raw    = file_get_contents( $tmp_name ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		$result = $this->plugin->settings->import_data( $raw, 'network' );

		$arg = is_wp_error( $result ) ? 'import_error' : 'imported';
		wp_safe_redirect( add_query_arg( $arg, '1', self::settings_url() ) );
		exit;
	}

	public function render_page() {
		if ( ! current_user_can( 'manage_network_options' ) ) {
			wp_die( esc_html__( 'Access denied.', 'core-version-switcher-by-volade' ) );
		}

		$settings     = $this->plugin->settings->all_network();
		$context      = 'network';
		$is_readonly  = false;
		$target       = CVS_Settings::sanitize_version( $settings['target_version'] ?? '' );
		$zip_url      = $target ? $this->plugin->settings->build_download_url( $target ) : '';
		$zip_ok       = $zip_url ? $this->plugin->settings->zip_exists( $zip_url ) : null;
		$log          = $this->plugin->settings->get_log();
		$presets      = CVS_Presets::all( $this->plugin );
		$releases     = CVS_Releases::get_recent_releases( 60, ! empty( $settings['show_insecure_in_picker'] ) );
		$diagnostics  = $this->plugin->diagnostics->run();
		$insights     = $target ? $this->plugin->settings->get_target_insights( $target ) : array();
		$rollback     = CVS_Settings::sanitize_version( get_option( CVS_Settings::PREVIOUS_VERSION_KEY, '' ) );
		$latest       = CVS_Releases::get_latest_version();
		$compat       = $target ? CVS_Preflight::compat_report( $target ) : array(
			'errors'   => array(),
			'warnings' => array(),
			'scan'     => array(
				'plugins' => array(),
				'themes'  => array(),
			),
		);
		$checksum     = CVS_Checksums::get_last_result();
		$pin_expires  = $this->plugin->settings->pin_expires_at();
		$access       = $this->plugin->volade ? $this->plugin->volade->get_access_level() : 'guest';
		$access_label = $this->plugin->volade ? $this->plugin->volade->get_access_level_label( $access ) : __( 'No account', 'core-version-switcher-by-volade' );
		if ( 'network' !== $access ) {
			$access = 'network';
		}
		$access_label = __( 'Multisite network', 'core-version-switcher-by-volade' );

		include CVS_DIR . 'admin/views/settings-page.php';
	}
}
