<?php
/**
 * Plugin global settings form and save handler.
 *
 * @since   1.0.0
 * @package DonationRouter
 */

declare( strict_types=1 );
namespace DonationRouter;

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

/**
 * Manages the Settings tab on the plugin admin page.
 *
 * Settings are stored as individual wp_options entries with the `ador_`
 * prefix.  This class registers the admin-post save action, handles
 * sanitisation, and renders the HTML form.
 *
 * @since 1.0.0
 */
class Plugin_Settings {

	use Template_Loader;

	/**
	 * Admin-post action for saving plugin settings.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public const ACTION_SAVE = 'ador_save_settings';

	/**
	 * Nonce action for the settings form.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public const NONCE_ACTION = 'ador_save_settings_nonce';

	/**
	 * Nonce field name.
	 *
	 * @since 1.0.0
	 *
	 * @var string
	 */
	public const NONCE_FIELD = 'ador_settings_nonce';

	/**
	 * Register WordPress hooks.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function register_hooks(): void {
		add_action( 'admin_post_' . self::ACTION_SAVE, array( $this, 'save' ) );
	}

	/**
	 * Handle the settings form POST submission.
	 *
	 * Verifies capability, nonce, sanitises and stores each setting, then
	 * redirects back to the Settings tab with a success notice.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function save(): void {
		if ( ! current_user_can( Admin_Settings::CAPABILITY ) ) {
			wp_die( esc_html__( 'You do not have permission to save these settings.', 'alamin-donation-router' ) );
		}

		check_admin_referer( self::NONCE_ACTION, self::NONCE_FIELD );

		// ── General ────────────────────────────────────────────────────────────

		$default_form_id = absint( $_POST['ador_default_form_id'] ?? 0 ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_default_form_id', $default_form_id );

		// ── Country selector popup ─────────────────────────────────────────────

		$popup_dismissible = isset( $_POST['ador_popup_dismissible'] ) ? (bool) $_POST['ador_popup_dismissible'] : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_popup_dismissible', $popup_dismissible );

		$allowed_triggers      = array( 'auto', 'button' );
		$popup_default_trigger = sanitize_key( (string) wp_unslash( $_POST['ador_popup_default_trigger'] ?? 'auto' ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		if ( ! in_array( $popup_default_trigger, $allowed_triggers, true ) ) {
			$popup_default_trigger = 'auto';
		}
		update_option( 'ador_popup_default_trigger', $popup_default_trigger );

		$popup_heading = sanitize_text_field( (string) wp_unslash( $_POST['ador_popup_heading_default'] ?? '' ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_popup_heading_default', $popup_heading );

		// ── Geolocation ────────────────────────────────────────────────────────

		$geolocation_enabled = isset( $_POST['ador_geolocation_enabled'] ) ? (bool) $_POST['ador_geolocation_enabled'] : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_geolocation_enabled', $geolocation_enabled );

		$allowed_providers    = array( 'cloudflare', 'maxmind', 'wp_filter' );
		$geolocation_provider = sanitize_key( (string) wp_unslash( $_POST['ador_geolocation_provider'] ?? 'cloudflare' ) ); // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		if ( ! in_array( $geolocation_provider, $allowed_providers, true ) ) {
			$geolocation_provider = 'cloudflare';
		}
		update_option( 'ador_geolocation_provider', $geolocation_provider );

		// ── PDF receipts ───────────────────────────────────────────────────────

		$pdf_enabled = isset( $_POST['ador_pdf_receipts_enabled'] ) ? (bool) $_POST['ador_pdf_receipts_enabled'] : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_pdf_receipts_enabled', $pdf_enabled );

		// ── Legal acknowledgement ──────────────────────────────────────────────

		$acknowledged = isset( $_POST['ador_receipt_legal_review_acknowledged'] ) ? (bool) $_POST['ador_receipt_legal_review_acknowledged'] : false; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.MissingUnslash,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
		update_option( 'ador_receipt_legal_review_acknowledged', $acknowledged );

		set_transient(
			'ador_admin_notice_' . get_current_user_id(),
			array(
				'type'    => 'success',
				'message' => __( 'Settings saved.', 'alamin-donation-router' ),
			),
			30
		);

		wp_safe_redirect(
			add_query_arg(
				array(
					'page' => Admin_Settings::MENU_SLUG,
					'tab'  => Admin_Settings::TAB_SETTINGS,
				),
				admin_url( 'edit.php?post_type=give_forms' )
			)
		);
		exit;
	}

	/**
	 * Render the settings form HTML.
	 *
	 * Outputs a standard WordPress settings form targeting the admin-post
	 * handler.  All values are read fresh from wp_options on each render.
	 *
	 * @since 1.0.0
	 *
	 * @return void
	 */
	public function render(): void {
		$default_form_id   = (int) get_option( 'ador_default_form_id', 0 );
		$popup_dismissible = (bool) get_option( 'ador_popup_dismissible', false );
		$popup_trigger     = (string) get_option( 'ador_popup_default_trigger', 'auto' );
		$popup_heading     = (string) get_option( 'ador_popup_heading_default', '' );
		$geo_enabled       = (bool) get_option( 'ador_geolocation_enabled', true );
		$geo_provider      = (string) get_option( 'ador_geolocation_provider', 'cloudflare' );
		$pdf_enabled       = (bool) get_option( 'ador_pdf_receipts_enabled', false );
		$acknowledged      = (bool) get_option( 'ador_receipt_legal_review_acknowledged', false );

		$give_forms  = get_posts(
			array(
				'post_type'      => 'give_forms',
				'posts_per_page' => 100,
				'post_status'    => 'publish',
				'orderby'        => 'title',
				'order'          => 'ASC',
			)
		);
		$form_action = add_query_arg( 'action', self::ACTION_SAVE, admin_url( 'admin-post.php' ) );

		$this->render_template(
			'admin/plugin-settings.php',
			compact( 'form_action', 'default_form_id', 'popup_dismissible', 'popup_trigger', 'popup_heading', 'geo_enabled', 'geo_provider', 'pdf_enabled', 'acknowledged', 'give_forms' )
		);
	}
}
