<?php
/**
 * Admin UI: one menu page, three tabs (cockpit / forms / settings), all
 * actions nonce + capability checked, CSS enqueued only on our screen, no JS.
 *
 * @package Form_Flight_Recorder
 */

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

/**
 * Admin controller.
 */
class Ffrd_Admin {

	/**
	 * Container.
	 *
	 * @var Ffrd_Plugin
	 */
	private $plugin;

	/**
	 * Menu hook suffix.
	 *
	 * @var string
	 */
	private $hook = '';

	/**
	 * Constructor.
	 *
	 * @param Ffrd_Plugin $plugin Container.
	 */
	public function __construct( $plugin ) {
		$this->plugin = $plugin;

		add_action( 'admin_menu', array( $this, 'menu' ) );
		add_action( 'admin_init', array( $this, 'handle_actions' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'assets' ) );
	}

	/**
	 * Menu page.
	 */
	public function menu() {
		$this->hook = add_menu_page(
			__( 'Form Flight Recorder', 'form-flight-recorder' ),
			__( 'Form Flight Recorder', 'form-flight-recorder' ),
			'manage_options',
			'ffrd',
			array( $this, 'render' ),
			'dashicons-forms',
			58
		);
	}

	/**
	 * CSS, only on our screen.
	 *
	 * @param string $hook Current admin page hook.
	 */
	public function assets( $hook ) {
		if ( $hook !== $this->hook ) {
			return;
		}
		wp_enqueue_style( 'ffrd-admin', FFRD_URL . 'admin/css/ffrd-admin.css', array(), FFRD_VERSION );
	}

	/**
	 * Tabs.
	 *
	 * @return array slug => label.
	 */
	public function tabs() {
		$tabs = array(
			'cockpit'  => __( 'Cockpit', 'form-flight-recorder' ),
			'forms'    => __( 'Forms', 'form-flight-recorder' ),
			'settings' => __( 'Settings', 'form-flight-recorder' ),
		);

		/**
		 * Filters the admin tabs (Pro adds its own).
		 *
		 * @param array $tabs slug => label.
		 */
		return apply_filters( 'ffrd_admin_tabs', $tabs );
	}

	/**
	 * Current tab (sanitized, whitelisted).
	 *
	 * @return string
	 */
	private function current_tab() {
		$tab  = isset( $_GET['tab'] ) ? sanitize_key( wp_unslash( $_GET['tab'] ) ) : 'cockpit'; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- read-only view routing.
		$tabs = $this->tabs();
		return isset( $tabs[ $tab ] ) ? $tab : 'cockpit';
	}

	/**
	 * POST actions. All require manage_options + a per-action nonce.
	 */
	public function handle_actions() {
		if ( ! isset( $_POST['ffrd_action'] ) ) {
			return;
		}
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$action = sanitize_key( wp_unslash( $_POST['ffrd_action'] ) );
		$nonce  = isset( $_POST['_wpnonce'] ) ? sanitize_text_field( wp_unslash( $_POST['_wpnonce'] ) ) : '';
		if ( ! wp_verify_nonce( $nonce, 'ffrd_' . $action ) ) {
			return;
		}

		$msg = 'saved';

		switch ( $action ) {
			case 'save_settings':
				$settings                   = $this->plugin->settings();
				$digest                     = isset( $_POST['ffrd_digest'] ) ? sanitize_key( wp_unslash( $_POST['ffrd_digest'] ) ) : 'weekly';
				$settings['digest']         = in_array( $digest, array( 'off', 'daily', 'weekly' ), true ) ? $digest : 'weekly';
				$email                      = isset( $_POST['ffrd_digest_email'] ) ? sanitize_email( wp_unslash( $_POST['ffrd_digest_email'] ) ) : '';
				$settings['digest_email']   = $email ? $email : get_option( 'admin_email' );
				$settings['instant_alerts'] = empty( $_POST['ffrd_instant_alerts'] ) ? 0 : 1;
				$hours                      = isset( $_POST['ffrd_silence_hours'] ) ? absint( wp_unslash( $_POST['ffrd_silence_hours'] ) ) : 48;
				$settings['silence_hours']  = max( 6, min( 24 * 30, $hours ? $hours : 48 ) );
				update_option( 'ffrd_settings', $settings, false );
				break;

			case 'save_forms':
				$rows = array();
				if ( isset( $_POST['ffrd_forms'] ) && is_array( $_POST['ffrd_forms'] ) ) {
					$rows = map_deep( wp_unslash( $_POST['ffrd_forms'] ), 'sanitize_text_field' ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- sanitized via map_deep(sanitize_text_field), then whitelisted field-by-field below.
				}
				$registry = $this->plugin->get( 'registry' );
				foreach ( $rows as $key => $row ) {
					if ( ! is_array( $row ) ) {
						continue;
					}
					$registry->set_overrides(
						sanitize_text_field( (string) $key ),
						isset( $row['expects'] ) ? sanitize_key( $row['expects'] ) : '',
						isset( $row['silence_hours'] ) ? absint( $row['silence_hours'] ) : 0
					);
				}
				$msg = 'forms_saved';
				break;

			case 'discover_now':
				$this->plugin->get( 'adapters' )->discover();
				$msg = 'discovered';
				break;

			default:
				/**
				 * Fires for unrecognized (Pro) admin actions. Nonce + capability
				 * already verified for the exact action name.
				 *
				 * @param Ffrd_Plugin $plugin Container.
				 */
				do_action( 'ffrd_admin_action_' . $action, $this->plugin );
				break;
		}

		$redirect = add_query_arg(
			array(
				'page'     => 'ffrd',
				'tab'      => $this->current_post_tab(),
				'ffrd_msg' => $msg,
			),
			admin_url( 'admin.php' )
		);
		wp_safe_redirect( $redirect );
		exit;
	}

	/**
	 * Tab to land on after a POST (whitelisted).
	 *
	 * @return string
	 */
	private function current_post_tab() {
		$tab  = isset( $_POST['ffrd_tab'] ) ? sanitize_key( wp_unslash( $_POST['ffrd_tab'] ) ) : 'cockpit'; // phpcs:ignore WordPress.Security.NonceVerification.Missing -- routing only; the action handler above verified the nonce.
		$tabs = $this->tabs();
		return isset( $tabs[ $tab ] ) ? $tab : 'cockpit';
	}

	/**
	 * Page render.
	 */
	public function render() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$plugin = $this->plugin;
		$tab    = $this->current_tab();
		$tabs   = $this->tabs();

		echo '<div class="wrap ffrd-wrap">';
		echo '<h1>' . esc_html__( 'Form Flight Recorder', 'form-flight-recorder' ) . '</h1>';

		$this->notice();

		echo '<nav class="nav-tab-wrapper ffrd-tabs">';
		foreach ( $tabs as $slug => $label ) {
			$url = add_query_arg(
				array(
					'page' => 'ffrd',
					'tab'  => $slug,
				),
				admin_url( 'admin.php' )
			);
			printf(
				'<a class="nav-tab %1$s" href="%2$s">%3$s</a>',
				esc_attr( $tab === $slug ? 'nav-tab-active' : '' ),
				esc_url( $url ),
				esc_html( $label )
			);
		}
		echo '</nav>';

		if ( 'cockpit' === $tab ) {
			include FFRD_DIR . 'admin/views/cockpit.php';
		} elseif ( 'forms' === $tab ) {
			include FFRD_DIR . 'admin/views/forms.php';
		} elseif ( 'settings' === $tab ) {
			include FFRD_DIR . 'admin/views/settings.php';
		} else {
			/**
			 * Renders a Pro-registered tab.
			 *
			 * @param Ffrd_Plugin $plugin Container.
			 */
			do_action( 'ffrd_render_tab_' . $tab, $plugin );
		}

		echo '</div>';
	}

	/**
	 * One-shot admin notice from the redirect flag (our page only).
	 */
	private function notice() {
		$msg = isset( $_GET['ffrd_msg'] ) ? sanitize_key( wp_unslash( $_GET['ffrd_msg'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- display-only flag on our own page.
		if ( ! $msg ) {
			return;
		}

		$map = array(
			'saved'       => __( 'Settings saved.', 'form-flight-recorder' ),
			'forms_saved' => __( 'Per-form settings saved.', 'form-flight-recorder' ),
			'discovered'  => __( 'Form discovery ran — the registry is up to date.', 'form-flight-recorder' ),
		);
		if ( ! isset( $map[ $msg ] ) ) {
			return;
		}

		echo '<div class="notice notice-success is-dismissible"><p>' . esc_html( $map[ $msg ] ) . '</p></div>';
	}
}
