<?php
/**
 * Admin settings screen for the Barnet connection.
 *
 * Credential handling rules enforced here:
 *  - The API password is never rendered back into the form. The field always
 *    renders empty; submitting it empty leaves the stored value untouched.
 *  - Credentials are never written to any log or printed in any notice.
 *  - If wp-config.php constants are present they win, and the fields are
 *    disabled so the screen cannot silently disagree with what is in force.
 */

defined( 'ABSPATH' ) || exit;

class BW_Barnet_Settings {

	const PAGE  = 'bw-barnet';
	const NONCE = 'bw_barnet_save';

	public static function init(): void {
		add_action( 'admin_menu', array( __CLASS__, 'menu' ) );
		add_action( 'admin_post_bw_barnet_save', array( __CLASS__, 'handle_save' ) );
		add_action( 'admin_post_bw_barnet_test', array( __CLASS__, 'handle_test' ) );
	}

	public static function menu(): void {
		add_menu_page(
			__( 'Barnet Connector', 'bw-barnet' ),
			__( 'Barnet', 'bw-barnet' ),
			BW_BARNET_CAP,
			self::PAGE,
			array( __CLASS__, 'render' ),
			'dashicons-store',
			56
		);

		add_submenu_page(
			self::PAGE,
			__( 'Connection Settings', 'bw-barnet' ),
			__( 'Settings', 'bw-barnet' ),
			BW_BARNET_CAP,
			self::PAGE,
			array( __CLASS__, 'render' )
		);
	}

	private static function redirect_with( array $args ): void {
		wp_safe_redirect( add_query_arg( $args, admin_url( 'admin.php?page=' . self::PAGE ) ) );
		exit;
	}

	public static function handle_save(): void {
		if ( ! current_user_can( BW_BARNET_CAP ) ) {
			wp_die( esc_html__( 'You do not have permission to change these settings.', 'bw-barnet' ) );
		}
		check_admin_referer( self::NONCE );

		$base = isset( $_POST['base_url'] ) ? esc_url_raw( wp_unslash( $_POST['base_url'] ) ) : '';
		if ( '' === $base ) {
			$base = BW_Barnet_Client::DEFAULT_BASE;
		}
		update_option( BW_Barnet_Client::OPT_BASE, untrailingslashit( $base ) );

		if ( isset( $_POST['api_key'] ) ) {
			update_option( BW_Barnet_Client::OPT_KEY, sanitize_text_field( wp_unslash( $_POST['api_key'] ) ) );
		}

		// Empty password field means "leave the stored secret alone".
		$pass = isset( $_POST['api_pass'] ) ? trim( (string) wp_unslash( $_POST['api_pass'] ) ) : '';
		if ( '' !== $pass ) {
			update_option( BW_Barnet_Client::OPT_PASS, $pass );
		}

		if ( isset( $_POST['account_id'] ) ) {
			update_option( BW_Barnet_Client::OPT_ACCOUNT, sanitize_text_field( wp_unslash( $_POST['account_id'] ) ) );
		}
		if ( isset( $_POST['shop_id'] ) ) {
			update_option( BW_Barnet_Client::OPT_SHOP, sanitize_text_field( wp_unslash( $_POST['shop_id'] ) ) );
		}

		self::redirect_with( array( 'bw_msg' => 'saved' ) );
	}

	public static function handle_test(): void {
		if ( ! current_user_can( BW_BARNET_CAP ) ) {
			wp_die( esc_html__( 'You do not have permission to run this test.', 'bw-barnet' ) );
		}
		check_admin_referer( self::NONCE );

		$result = BW_Barnet_Client::test_connection();

		if ( is_wp_error( $result ) ) {
			set_transient( 'bw_barnet_test_result', array( 'ok' => false, 'message' => $result->get_error_message() ), 120 );
		} else {
			set_transient( 'bw_barnet_test_result', array( 'ok' => true, 'data' => $result ), 120 );
		}

		self::redirect_with( array( 'bw_msg' => 'tested' ) );
	}

	public static function render(): void {
		if ( ! current_user_can( BW_BARNET_CAP ) ) {
			return;
		}

		$creds        = BW_Barnet_Client::credentials();
		$by_constants = 'constants' === $creds['source'];
		$has_pass     = '' !== $creds['pass'];
		$test         = get_transient( 'bw_barnet_test_result' );
		if ( $test ) {
			delete_transient( 'bw_barnet_test_result' );
		}
		?>
		<div class="wrap">
			<h1><?php esc_html_e( 'Barnet Connector', 'bw-barnet' ); ?></h1>

			<?php if ( isset( $_GET['bw_msg'] ) && 'saved' === $_GET['bw_msg'] ) : ?>
				<div class="notice notice-success is-dismissible"><p><?php esc_html_e( 'Settings saved.', 'bw-barnet' ); ?></p></div>
			<?php endif; ?>

			<?php if ( is_array( $test ) ) : ?>
				<?php if ( ! empty( $test['ok'] ) ) : ?>
					<div class="notice notice-success">
						<p><strong><?php esc_html_e( 'Connection succeeded.', 'bw-barnet' ); ?></strong></p>
						<p>
							<?php
							$count = $test['data']['items_count'] ?? null;
							if ( null !== $count ) {
								printf(
									/* translators: %s: number of catalogue items */
									esc_html__( 'Barnet reports %s items in the catalogue.', 'bw-barnet' ),
									'<strong>' . esc_html( number_format_i18n( $count ) ) . '</strong>'
								);
							}
							?>
						</p>
						<?php if ( ! empty( $test['data']['sample_keys'] ) ) : ?>
							<p><em><?php esc_html_e( 'Fields returned on a product:', 'bw-barnet' ); ?></em><br>
							<code style="font-size:11px"><?php echo esc_html( implode( ', ', $test['data']['sample_keys'] ) ); ?></code></p>
						<?php endif; ?>
					</div>
				<?php else : ?>
					<div class="notice notice-error">
						<p><strong><?php esc_html_e( 'Connection failed.', 'bw-barnet' ); ?></strong></p>
						<p><?php echo esc_html( $test['message'] ?? '' ); ?></p>
					</div>
				<?php endif; ?>
			<?php endif; ?>

			<?php if ( $by_constants ) : ?>
				<div class="notice notice-info">
					<p><?php esc_html_e( 'Credentials are being supplied by BARNET_API_KEY and BARNET_API_PASS in wp-config.php. Those take precedence, so the fields below are disabled.', 'bw-barnet' ); ?></p>
				</div>
			<?php endif; ?>

			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<input type="hidden" name="action" value="bw_barnet_save">
				<?php wp_nonce_field( self::NONCE ); ?>

				<table class="form-table" role="presentation">
					<tr>
						<th scope="row"><label for="base_url"><?php esc_html_e( 'API base URL', 'bw-barnet' ); ?></label></th>
						<td>
							<input name="base_url" id="base_url" type="url" class="regular-text code"
								value="<?php echo esc_attr( BW_Barnet_Client::base_url() ); ?>">
							<p class="description">
								<?php esc_html_e( 'Must be https. Barnet\'s documentation says http, but https works and http would send your credentials in cleartext. The connector refuses to make non-https requests.', 'bw-barnet' ); ?>
							</p>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="api_key"><?php esc_html_e( 'API key', 'bw-barnet' ); ?></label></th>
						<td>
							<input name="api_key" id="api_key" type="text" class="regular-text code" autocomplete="off"
								<?php disabled( $by_constants ); ?>
								value="<?php echo $by_constants ? '' : esc_attr( get_option( BW_Barnet_Client::OPT_KEY, '' ) ); ?>">
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="api_pass"><?php esc_html_e( 'API password', 'bw-barnet' ); ?></label></th>
						<td>
							<input name="api_pass" id="api_pass" type="password" class="regular-text code" autocomplete="new-password"
								<?php disabled( $by_constants ); ?>
								placeholder="<?php echo $has_pass ? esc_attr__( '•••••••• (stored, leave blank to keep)', 'bw-barnet' ) : esc_attr__( 'not set', 'bw-barnet' ); ?>">
							<p class="description">
								<?php esc_html_e( 'Never displayed once saved. Leave blank to keep the existing value.', 'bw-barnet' ); ?>
							</p>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="account_id"><?php esc_html_e( 'Account ID', 'bw-barnet' ); ?></label></th>
						<td>
							<input name="account_id" id="account_id" type="text" class="regular-text code"
								value="<?php echo esc_attr( BW_Barnet_Client::account_id() ); ?>">
							<p class="description"><?php esc_html_e( 'The "XXX" in /api/ui/shop/XXX-YYY/filters. Optional until we use the filters endpoint.', 'bw-barnet' ); ?></p>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="shop_id"><?php esc_html_e( 'Shop ID', 'bw-barnet' ); ?></label></th>
						<td>
							<input name="shop_id" id="shop_id" type="text" class="regular-text code"
								value="<?php echo esc_attr( BW_Barnet_Client::shop_id() ); ?>">
							<p class="description"><?php esc_html_e( 'The "YYY" in the same path.', 'bw-barnet' ); ?></p>
						</td>
					</tr>
				</table>

				<?php submit_button( __( 'Save settings', 'bw-barnet' ) ); ?>
			</form>

			<hr>

			<h2><?php esc_html_e( 'Test the connection', 'bw-barnet' ); ?></h2>
			<p><?php esc_html_e( 'Makes one authenticated request for a single product and reports what came back.', 'bw-barnet' ); ?></p>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<input type="hidden" name="action" value="bw_barnet_test">
				<?php wp_nonce_field( self::NONCE ); ?>
				<?php submit_button( __( 'Test connection', 'bw-barnet' ), 'secondary', 'submit', false, BW_Barnet_Client::has_credentials() ? array() : array( 'disabled' => 'disabled' ) ); ?>
				<?php if ( ! BW_Barnet_Client::has_credentials() ) : ?>
					<p class="description"><?php esc_html_e( 'Enter and save credentials first.', 'bw-barnet' ); ?></p>
				<?php endif; ?>
			</form>
		</div>
		<?php
	}
}
