<?php
/**
 * RSM Buttons admin screens.
 *
 * @package Rsmspark_Content_Widgets
 */

defined( 'ABSPATH' ) || exit;

/**
 * Rsmspark_Buttons_Admin
 */
class Rsmspark_Buttons_Admin {

	const PAGE_SLUG = 'rsmspark-buttons';

	/**
	 * @return void
	 */
	public static function init() {
		if ( ! class_exists( 'Rsmspark_Suite', false ) ) {
			add_action( 'admin_menu', array( __CLASS__, 'register_menu' ), 10 );
		}

		add_action( 'admin_enqueue_scripts', array( __CLASS__, 'enqueue_assets' ) );
		add_action( 'admin_post_rsmspark_buttons_save', array( __CLASS__, 'handle_save' ) );
		add_action( 'admin_post_rsmspark_buttons_settings_save', array( __CLASS__, 'handle_settings_save' ) );
		add_action( 'admin_init', array( __CLASS__, 'handle_actions' ) );
		add_filter( 'parent_file', array( __CLASS__, 'filter_parent_file' ) );
		add_filter( 'submenu_file', array( __CLASS__, 'filter_submenu_file' ) );
		add_filter( 'admin_body_class', array( __CLASS__, 'admin_body_class' ) );
	}

	/**
	 * Keep Content Widgets highlighted when viewing Buttons.
	 *
	 * @param string $parent_file Parent file.
	 * @return string
	 */
	public static function filter_parent_file( $parent_file ) {
		global $plugin_page;

		if ( self::PAGE_SLUG === $plugin_page ) {
			return class_exists( 'Rsmspark_Suite', false ) ? Rsmspark_Suite::parent_slug() : Rsmspark_Content_Widgets_Admin::PAGE_SLUG;
		}

		return $parent_file;
	}

	/**
	 * Register under the RSM suite menu (indented below Content Widgets).
	 *
	 * @return void
	 */
	public static function register_menu() {
		$cap        = self::capability();
		$menu_title = __( 'Buttons', 'rsm-content-widgets' );
		$parent     = Rsmspark_Content_Widgets_Admin::PAGE_SLUG;

		if ( class_exists( 'Rsmspark_Suite', false ) ) {
			Rsmspark_Suite::register_parent();
			$parent     = Rsmspark_Suite::parent_slug();
			$menu_title = '— ' . $menu_title;
		}

		add_submenu_page(
			$parent,
			__( 'Buttons', 'rsm-content-widgets' ),
			$menu_title,
			$cap,
			self::PAGE_SLUG,
			array( __CLASS__, 'render_router' )
		);
	}

	/**
	 * Highlight the Buttons item in the suite submenu.
	 *
	 * @param string $submenu_file Submenu file.
	 * @return string
	 */
	public static function filter_submenu_file( $submenu_file ) {
		global $plugin_page;

		if ( self::PAGE_SLUG === $plugin_page ) {
			return self::PAGE_SLUG;
		}

		return $submenu_file;
	}

	/**
	 * @param string $classes Admin body classes.
	 * @return string
	 */
	public static function admin_body_class( $classes ) {
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;

		if ( $screen && false !== strpos( (string) $screen->id, self::PAGE_SLUG ) ) {
			$classes .= ' rsmspark-suite-admin-screen';
		}

		return $classes;
	}

	/**
	 * @return string
	 */
	public static function capability() {
		if ( current_user_can( 'manage_rsm_buttons' ) ) {
			return 'manage_rsm_buttons';
		}

		return 'manage_options';
	}

	/**
	 * @param string $hook Hook.
	 * @return void
	 */
	public static function enqueue_assets( $hook ) {
		$screen = function_exists( 'get_current_screen' ) ? get_current_screen() : null;
		$load   = ( false !== strpos( (string) $hook, self::PAGE_SLUG ) )
			|| ( $screen && false !== strpos( (string) $screen->id, self::PAGE_SLUG ) );

		if ( ! $load ) {
			return;
		}

		if ( function_exists( 'rsmspark_suite_enqueue_admin_styles' ) ) {
			rsmspark_suite_enqueue_admin_styles( RSMSPARK_CONTENT_WIDGETS_PATH . 'rsm-shared', RSMSPARK_CONTENT_WIDGETS_URL . 'rsm-shared', RSMSPARK_CONTENT_WIDGETS_VERSION );
		} elseif ( class_exists( 'Rsmspark_Suite', false ) ) {
			Rsmspark_Suite::enqueue_local_admin_styles( RSMSPARK_CONTENT_WIDGETS_PATH . 'rsm-shared', RSMSPARK_CONTENT_WIDGETS_URL . 'rsm-shared', RSMSPARK_CONTENT_WIDGETS_VERSION );
		}

		wp_enqueue_style(
			'rsmspark-content-widgets-admin',
			RSMSPARK_CONTENT_WIDGETS_URL . 'assets/css/admin-widgets.css',
			array( 'rsmspark-suite-admin', 'rsmspark-suite-buttons' ),
			RSMSPARK_CONTENT_WIDGETS_VERSION
		);
		if ( defined( 'RSMSPARK_SUITE_URL' ) && defined( 'RSMSPARK_SUITE_VERSION' ) ) {
			wp_enqueue_script(
				'rsmspark-suite-admin-ui',
				RSMSPARK_SUITE_URL . 'assets/js/admin-suite-ui.js',
				array(),
				RSMSPARK_SUITE_VERSION,
				true
			);
		}
		wp_enqueue_style( 'wp-color-picker' );
		wp_enqueue_style(
			'rsmspark-buttons',
			RSMSPARK_CONTENT_WIDGETS_URL . 'assets/css/rsm-buttons.css',
			array(),
			RSMSPARK_CONTENT_WIDGETS_VERSION
		);
		wp_enqueue_style(
			'rsmspark-buttons-admin',
			RSMSPARK_CONTENT_WIDGETS_URL . 'assets/css/rsm-buttons-admin.css',
			array( 'rsmspark-buttons', 'wp-color-picker', 'rsmspark-content-widgets-admin' ),
			RSMSPARK_CONTENT_WIDGETS_VERSION
		);
		wp_enqueue_style(
			'rsmspark-content-widgets-admin-hub',
			RSMSPARK_CONTENT_WIDGETS_URL . 'assets/css/admin-hub.css',
			array( 'rsmspark-suite-admin', 'rsmspark-suite-buttons', 'rsmspark-content-widgets-admin', 'rsmspark-buttons-admin' ),
			RSMSPARK_CONTENT_WIDGETS_VERSION
		);

		wp_enqueue_script( 'wp-color-picker' );
		if ( self::is_edit_screen() ) {
			wp_enqueue_media();
		}

		$script_deps = array( 'jquery', 'wp-color-picker', 'media-upload', 'wp-media-utils' );
		if ( class_exists( 'RSM_Media_Picker', false ) && RSM_Media_Picker::should_enqueue() ) {
			$script_deps[] = 'rsm-media-picker-bridge';
		}

		wp_enqueue_script(
			'rsmspark-buttons-admin',
			RSMSPARK_CONTENT_WIDGETS_URL . 'assets/js/rsm-buttons-admin.js',
			$script_deps,
			RSMSPARK_CONTENT_WIDGETS_VERSION,
			true
		);

		wp_localize_script(
			'rsmspark-buttons-admin',
			'rsmsparkButtonsAdmin',
			array(
				'ajaxUrl' => admin_url( 'admin-ajax.php' ),
				'nonce'   => wp_create_nonce( 'rsmspark_buttons_admin' ),
				'icons'            => Rsmspark_Buttons_Icons::get_picker_choices(),
				'iconCategories'   => Rsmspark_Buttons_Icons::get_categories(),
				'presets' => self::preset_choices(),
				'i18n'    => array(
					'copied'       => __( 'Shortcode copied!', 'rsm-content-widgets' ),
					'search'       => __( 'Search pages & posts…', 'rsm-content-widgets' ),
					'noResults'    => __( 'No results found.', 'rsm-content-widgets' ),
					'iconNone'     => __( 'No icon', 'rsm-content-widgets' ),
					'iconCustom'   => __( 'Custom class', 'rsm-content-widgets' ),
					'pickIcon'     => __( 'Choose an icon', 'rsm-content-widgets' ),
					'selectImage'  => __( 'Select icon image', 'rsm-content-widgets' ),
					'removeImage'  => __( 'Remove image', 'rsm-content-widgets' ),
					'applyPreset'  => __( 'Apply this style preset? Existing style values will be overwritten.', 'rsm-content-widgets' ),
				),
			)
		);
	}

	/**
	 * @return bool
	 */
	private static function is_edit_screen() {
		// phpcs:disable WordPress.Security.NonceVerification.Recommended -- Read-only admin routing parameters; no state change.
		if ( empty( $_GET['page'] ) || self::PAGE_SLUG !== sanitize_key( wp_unslash( (string) $_GET['page'] ) ) ) {
			return false;
		}

		$action = sanitize_key( wp_unslash( (string) ( $_GET['action'] ?? 'list' ) ) );
		// phpcs:enable WordPress.Security.NonceVerification.Recommended
		return in_array( $action, array( 'edit', 'new' ), true );
	}

	/**
	 * @return array<int, array{slug: string, label: string, pro?: bool, config: array<string, mixed>}>
	 */
	public static function preset_choices() {
		$choices = array();
		foreach ( Rsmspark_Buttons_Presets::all() as $slug => $preset ) {
			if ( ! empty( $preset['pro'] ) ) {
				continue;
			}

			$choices[] = array(
				'slug'   => (string) $slug,
				'label'  => (string) ( $preset['label'] ?? $slug ),
				'pro'    => false,
				'config' => is_array( $preset['config'] ?? null ) ? $preset['config'] : array(),
			);
		}

		return $choices;
	}

	/**
	 * @deprecated 2.6.0 Use Rsmspark_Buttons_Icons::get_picker_choices().
	 * @return array<int, array{slug: string, label: string}>
	 */
	public static function dashicon_choices() {
		$choices = array();
		foreach ( Rsmspark_Buttons_Icons::get_picker_choices() as $choice ) {
			$choices[] = array(
				'slug'  => (string) ( $choice['slug'] ?? '' ),
				'label' => (string) ( $choice['label'] ?? '' ),
			);
		}

		return apply_filters( 'rsmspark_buttons_dashicon_choices', $choices );
	}

	/**
	 * @return array<int, array{slug: string, label: string, category: string}>
	 */
	public static function sprite_choices() {
		return Rsmspark_Buttons_Icons::get_picker_choices();
	}

	/**
	 * @param array<string, mixed> $args Query args.
	 * @return string
	 */
	public static function list_url( array $args = array() ) {
		return add_query_arg( array_merge( array( 'page' => self::PAGE_SLUG ), $args ), admin_url( 'admin.php' ) );
	}

	/**
	 * @return string
	 */
	public static function settings_url() {
		return self::tab_url( 'settings' );
	}

	/**
	 * @param string               $tab  Tab id.
	 * @param array<string, mixed> $args Extra query args.
	 * @return string
	 */
	public static function tab_url( $tab, array $args = array() ) {
		return self::list_url( array_merge( array( 'tab' => sanitize_key( $tab ) ), $args ) );
	}

	/**
	 * @param int $button_id Button ID.
	 * @return string
	 */
	public static function edit_url( $button_id = 0 ) {
		$args = array( 'action' => 'edit' );
		if ( $button_id > 0 ) {
			$args['button_id'] = absint( $button_id );
		}
		return self::list_url( $args );
	}

	/**
	 * @return void
	 */
	public static function render_router() {
		if ( ! current_user_can( self::capability() ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'rsm-content-widgets' ) );
		}

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin routing parameter; no state change.
		$action = sanitize_key( wp_unslash( (string) ( $_GET['action'] ?? '' ) ) );

		if ( 'settings' === $action ) {
			wp_safe_redirect( self::tab_url( 'settings' ) );
			exit;
		}

		if ( 'edit' === $action || 'new' === $action ) {
			self::render_edit_screen();
			return;
		}

		self::render_index_screen();
	}

	/**
	 * @return void
	 */
	public static function render_index_screen() {
		$table    = new Rsmspark_Buttons_List_Table();
		$table->prepare_items();
		$settings = Rsmspark_Buttons_Settings::get();
		require RSMSPARK_CONTENT_WIDGETS_PATH . 'admin/views/buttons-index.php';
	}

	/**
	 * @deprecated 2.4.1 Use render_index_screen().
	 * @return void
	 */
	public static function render_list_screen() {
		self::render_index_screen();
	}

	/**
	 * @deprecated 2.4.1 Settings are a tab in render_index_screen().
	 * @return void
	 */
	public static function render_settings_screen() {
		wp_safe_redirect( self::tab_url( 'settings' ) );
		exit;
	}

	/**
	 * @return void
	 */
	public static function render_edit_screen() {
		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin routing parameter; no state change.
		$button_id = isset( $_GET['button_id'] ) ? absint( wp_unslash( $_GET['button_id'] ) ) : 0;
		$post      = $button_id ? get_post( $button_id ) : null;
		$is_new    = ! $post || ! Rsmspark_Buttons_CPT::is_button_post( $button_id );

		$config = $is_new ? Rsmspark_Buttons_Config::defaults() : Rsmspark_Buttons_Config::get( $button_id );
		$title  = $is_new ? '' : $post->post_title;

		// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only admin notice flag; no state change.
		$updated = isset( $_GET['updated'] ) ? sanitize_text_field( wp_unslash( (string) $_GET['updated'] ) ) : '';
		if ( '1' === $updated ) {
			rsmspark_suite_render_admin_notice( __( 'Button saved.', 'rsm-content-widgets' ) );
		}

		require RSMSPARK_CONTENT_WIDGETS_PATH . 'admin/views/button-edit.php';
	}

	/**
	 * @return void
	 */
	public static function handle_save() {
		if ( ! current_user_can( self::capability() ) ) {
			wp_die( esc_html__( 'Permission denied.', 'rsm-content-widgets' ) );
		}

		check_admin_referer( 'rsmspark_buttons_save' );

		$button_id = absint( $_POST['button_id'] ?? 0 );
		$title     = sanitize_text_field( wp_unslash( (string) ( $_POST['button_title'] ?? '' ) ) );
		$raw       = isset( $_POST['rsmspark_button'] ) && is_array( $_POST['rsmspark_button'] ) ? wp_unslash( $_POST['rsmspark_button'] ) : array(); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated immediately by Rsmspark_Buttons_Config::sanitize().
		$config    = Rsmspark_Buttons_Config::sanitize( $raw );

		if ( '' === trim( $config['text_line_1'] ) ) {
			wp_die( esc_html__( 'Text line 1 is required.', 'rsm-content-widgets' ) );
		}

		$post_title = '' !== $title ? $title : $config['text_line_1'];
		$post_args  = array(
			'post_type'   => Rsmspark_Buttons_Config::CPT,
			'post_status' => 'publish',
			'post_title'  => $post_title,
			'post_author' => get_current_user_id(),
		);

		if ( $button_id > 0 && Rsmspark_Buttons_CPT::is_button_post( $button_id ) ) {
			$post_args['ID'] = $button_id;
			$result          = wp_update_post( $post_args, true );
		} else {
			$result    = wp_insert_post( $post_args, true );
			$button_id = is_wp_error( $result ) ? 0 : (int) $result;
		}

		if ( is_wp_error( $result ) ) {
			wp_die( esc_html( $result->get_error_message() ) );
		}

		if ( $button_id <= 0 ) {
			wp_die( esc_html__( 'Could not save the button. Please try again.', 'rsm-content-widgets' ) );
		}

		Rsmspark_Buttons_Config::save( (int) $button_id, $config );

		if ( ! empty( $_POST['save_duplicate'] ) ) {
			$duplicate_id = wp_insert_post(
				array(
					'post_type'   => Rsmspark_Buttons_Config::CPT,
					'post_status' => 'publish',
					'post_title'  => get_the_title( $button_id ) . ' ' . __( '(Copy)', 'rsm-content-widgets' ),
					'post_author' => get_current_user_id(),
				),
				true
			);
			if ( ! is_wp_error( $duplicate_id ) ) {
				Rsmspark_Buttons_Config::save( (int) $duplicate_id, $config );
				wp_safe_redirect( self::edit_url( (int) $duplicate_id ) . '&updated=1' );
				exit;
			}
		}

		wp_safe_redirect( self::edit_url( (int) $button_id ) . '&updated=1' );
		exit;
	}

	/**
	 * @return void
	 */
	public static function handle_settings_save() {
		if ( ! current_user_can( self::capability() ) ) {
			wp_die( esc_html__( 'Permission denied.', 'rsm-content-widgets' ) );
		}

		check_admin_referer( 'rsmspark_buttons_settings_save' );

		$raw = isset( $_POST['rsmspark_buttons_settings'] ) && is_array( $_POST['rsmspark_buttons_settings'] )
			? wp_unslash( $_POST['rsmspark_buttons_settings'] ) // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Validated immediately by Rsmspark_Buttons_Settings::save().
			: array();

		Rsmspark_Buttons_Settings::save( $raw );

		wp_safe_redirect( self::tab_url( 'settings', array( 'updated' => '1' ) ) );
		exit;
	}

	/**
	 * @return void
	 */
	public static function handle_actions() {
		$request_method = isset( $_SERVER['REQUEST_METHOD'] )
			? sanitize_text_field( wp_unslash( (string) $_SERVER['REQUEST_METHOD'] ) )
			: '';
		if ( 'POST' === $request_method ) {
			self::handle_post_actions();
			return;
		}

		self::handle_get_actions();
	}

	/**
	 * @return void
	 */
	private static function handle_post_actions() {
		if ( empty( $_POST['page'] ) || self::PAGE_SLUG !== sanitize_key( wp_unslash( (string) $_POST['page'] ) ) ) {
			return;
		}

		if ( ! current_user_can( self::capability() ) ) {
			return;
		}

		if ( empty( $_POST['button_ids'] ) || ! is_array( $_POST['button_ids'] ) ) {
			return;
		}

		check_admin_referer( 'bulk-rsm_buttons' );

		$bulk = '-1';
		if ( isset( $_POST['action'] ) && '-1' !== $_POST['action'] ) {
			$bulk = sanitize_key( wp_unslash( (string) $_POST['action'] ) );
		} elseif ( isset( $_POST['action2'] ) && '-1' !== $_POST['action2'] ) {
			$bulk = sanitize_key( wp_unslash( (string) $_POST['action2'] ) );
		}

		if ( '-1' === $bulk ) {
			return;
		}

		$ids = array_map( 'absint', wp_unslash( $_POST['button_ids'] ) );

		foreach ( $ids as $id ) {
			if ( $id <= 0 || ! Rsmspark_Buttons_CPT::is_button_post( $id ) ) {
				continue;
			}

			if ( 'delete' === $bulk ) {
				wp_trash_post( $id );
			} elseif ( 'duplicate' === $bulk ) {
				$config = Rsmspark_Buttons_Config::get( $id );
				$new_id = wp_insert_post(
					array(
						'post_type'   => Rsmspark_Buttons_Config::CPT,
						'post_status' => 'publish',
						'post_title'  => get_the_title( $id ) . ' ' . __( '(Copy)', 'rsm-content-widgets' ),
						'post_author' => get_current_user_id(),
					),
					true
				);
				if ( ! is_wp_error( $new_id ) ) {
					Rsmspark_Buttons_Config::save( (int) $new_id, $config );
				}
			}
		}

		wp_safe_redirect( self::tab_url( 'buttons' ) );
		exit;
	}

	/**
	 * @return void
	 */
	private static function handle_get_actions() {
		if ( empty( $_GET['page'] ) || self::PAGE_SLUG !== sanitize_key( wp_unslash( (string) $_GET['page'] ) ) ) {
			return;
		}

		if ( ! current_user_can( self::capability() ) ) {
			return;
		}

		$action    = sanitize_key( wp_unslash( (string) ( $_GET['action'] ?? '' ) ) );
		$button_id = absint( $_GET['button_id'] ?? 0 );

		if ( 'duplicate' === $action && $button_id > 0 ) {
			check_admin_referer( 'rsmspark_buttons_duplicate_' . $button_id );
			$config = Rsmspark_Buttons_Config::get( $button_id );
			$new_id = wp_insert_post(
				array(
					'post_type'   => Rsmspark_Buttons_Config::CPT,
					'post_status' => 'publish',
					'post_title'  => get_the_title( $button_id ) . ' ' . __( '(Copy)', 'rsm-content-widgets' ),
					'post_author' => get_current_user_id(),
				),
				true
			);
			if ( ! is_wp_error( $new_id ) ) {
				Rsmspark_Buttons_Config::save( (int) $new_id, $config );
			}
			wp_safe_redirect( self::tab_url( 'buttons' ) );
			exit;
		}

		if ( 'trash' === $action && $button_id > 0 ) {
			check_admin_referer( 'rsmspark_buttons_trash_' . $button_id );
			wp_trash_post( $button_id );
			wp_safe_redirect( self::tab_url( 'buttons' ) );
			exit;
		}
	}
}
