<?php
/**
 * Admin settings screen for BW 2Checkout Pricing.
 *
 * Lives at Settings → BW 2Checkout Pricing. Stores everything in one option; the Secret Key
 * is write-only in the UI (never rendered back) and prefers a wp-config constant.
 *
 * @package BW_2Checkout_Pricing
 */

defined( 'ABSPATH' ) || exit;

class BW_2Checkout_Pricing_Settings {

	const OPTION = 'bw_2checkout_pricing_settings';
	const PAGE   = 'bw-2checkout-pricing';
	const GROUP  = 'bw_2checkout_pricing_group';

	public function __construct() {
		add_action( 'admin_menu', array( $this, 'add_menu' ) );
		add_action( 'admin_init', array( $this, 'register' ) );
		add_action( 'admin_post_bw_2checkout_pricing_test', array( $this, 'handle_test_connection' ) );
		add_action( 'admin_notices', array( $this, 'maybe_render_test_notice' ) );
	}

	public function add_menu() {
		add_options_page(
			__( 'BW 2Checkout Pricing', 'bw-2checkout-pricing' ),
			__( 'BW 2Checkout Pricing', 'bw-2checkout-pricing' ),
			'manage_options',
			self::PAGE,
			array( $this, 'render_page' )
		);
	}

	public function register() {
		register_setting(
			self::GROUP,
			self::OPTION,
			array( 'sanitize_callback' => array( $this, 'sanitize' ) )
		);
	}

	/**
	 * Sanitize + persist. Merges over existing so blank fields never wipe stored values,
	 * and the Secret Key is preserved on blank / ignored when a constant is set.
	 *
	 * @param mixed $input Raw posted option value.
	 * @return array
	 */
	public function sanitize( $input ) {
		$existing = bw_2checkout_pricing_get_settings();
		if ( ! is_array( $input ) ) {
			return $existing;
		}
		$input = wp_unslash( $input );
		$out   = $existing;

		$out['merchant_code'] = isset( $input['merchant_code'] ) ? sanitize_text_field( $input['merchant_code'] ) : $existing['merchant_code'];

		// Secret key: constant wins; otherwise keep existing when left blank.
		if ( defined( 'BW_2CHECKOUT_PRICING_SECRET_KEY' ) && BW_2CHECKOUT_PRICING_SECRET_KEY ) {
			$out['secret_key'] = '';
		} else {
			$posted = isset( $input['secret_key'] ) ? trim( (string) $input['secret_key'] ) : '';
			if ( '' !== $posted ) {
				$out['secret_key'] = sanitize_text_field( $posted );
			}
		}

		$out['api_base'] = ! empty( $input['api_base'] ) ? esc_url_raw( trim( $input['api_base'] ) ) : 'https://api.2checkout.com/rest/6.0/';
		$out['checkout_base'] = ! empty( $input['checkout_base'] ) ? esc_url_raw( trim( $input['checkout_base'] ) ) : $existing['checkout_base'];
		$out['checkout_tpl']  = isset( $input['checkout_tpl'] ) ? sanitize_text_field( $input['checkout_tpl'] ) : $existing['checkout_tpl'];
		$out['test_mode']     = ! empty( $input['test_mode'] );
		$out['cache_ttl']     = isset( $input['cache_ttl'] ) ? absint( $input['cache_ttl'] ) : $existing['cache_ttl'];
		$out['default_currency'] = isset( $input['default_currency'] ) ? strtoupper( sanitize_text_field( $input['default_currency'] ) ) : $existing['default_currency'];

		if ( isset( $input['currencies'] ) ) {
			$codes = array_filter( array_map(
				static function ( $c ) {
					return preg_replace( '/[^A-Z]/', '', strtoupper( trim( $c ) ) );
				},
				explode( ',', (string) $input['currencies'] )
			) );
			$out['currencies'] = implode( ',', array_unique( $codes ) );
		}

		// Products config (JSON textarea).
		if ( isset( $input['products_json'] ) ) {
			$raw = trim( (string) $input['products_json'] );
			if ( '' === $raw ) {
				$out['products'] = array();
			} else {
				$decoded = json_decode( $raw, true );
				if ( is_array( $decoded ) ) {
					$out['products'] = $decoded;
				} else {
					add_settings_error( self::OPTION, 'bad_json', __( 'Products config was not valid JSON — kept the previous value.', 'bw-2checkout-pricing' ) );
				}
			}
		}

		BW_2Checkout_Pricing_Client::flush_cache();
		return $out;
	}

	public function render_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		$s              = bw_2checkout_pricing_get_settings();
		$secret_const   = defined( 'BW_2CHECKOUT_PRICING_SECRET_KEY' ) && BW_2CHECKOUT_PRICING_SECRET_KEY;
		$merchant_const = defined( 'BW_2CHECKOUT_PRICING_MERCHANT_CODE' ) && BW_2CHECKOUT_PRICING_MERCHANT_CODE;
		$configured     = ( new BW_2Checkout_Pricing_Client() )->is_configured();
		$has_secret     = $secret_const || '' !== (string) $s['secret_key'];
		$products_json  = empty( $s['products'] ) ? '' : wp_json_encode( $s['products'], JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES );
		$name           = self::OPTION;
		?>
		<div class="wrap">
			<h1><?php esc_html_e( 'BW 2Checkout Pricing', 'bw-2checkout-pricing' ); ?></h1>

			<p>
				<?php esc_html_e( 'Status:', 'bw-2checkout-pricing' ); ?>
				<strong style="color:<?php echo $configured ? '#1a7f37' : '#b32d2e'; ?>">
					<?php echo $configured ? esc_html__( 'credentials present', 'bw-2checkout-pricing' ) : esc_html__( 'not configured', 'bw-2checkout-pricing' ); ?>
				</strong>
			</p>

			<form method="post" action="options.php">
				<?php settings_fields( self::GROUP ); ?>
				<table class="form-table" role="presentation">
					<tr>
						<th scope="row"><label for="bw2cp_merchant"><?php esc_html_e( 'Merchant Code', 'bw-2checkout-pricing' ); ?></label></th>
						<td>
							<?php if ( $merchant_const ) : ?>
								<input type="text" id="bw2cp_merchant" value="<?php echo esc_attr( BW_2CHECKOUT_PRICING_MERCHANT_CODE ); ?>" class="regular-text" disabled />
								<p class="description"><?php esc_html_e( 'Defined via the BW_2CHECKOUT_PRICING_MERCHANT_CODE constant in wp-config.php.', 'bw-2checkout-pricing' ); ?></p>
							<?php else : ?>
								<input type="text" id="bw2cp_merchant" name="<?php echo esc_attr( $name ); ?>[merchant_code]" value="<?php echo esc_attr( $s['merchant_code'] ); ?>" class="regular-text" autocomplete="off" />
								<p class="description"><?php esc_html_e( 'From 2Checkout: Integrations → Webhooks & API. For Copernic this is COPERNIC.', 'bw-2checkout-pricing' ); ?></p>
							<?php endif; ?>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_secret"><?php esc_html_e( 'Secret Key', 'bw-2checkout-pricing' ); ?></label></th>
						<td>
							<?php if ( $secret_const ) : ?>
								<em><?php esc_html_e( 'Defined via the BW_2CHECKOUT_PRICING_SECRET_KEY constant in wp-config.php (recommended for production).', 'bw-2checkout-pricing' ); ?></em>
							<?php else : ?>
								<input type="password" id="bw2cp_secret" name="<?php echo esc_attr( $name ); ?>[secret_key]" value="" class="regular-text" autocomplete="new-password"
									placeholder="<?php echo $has_secret ? esc_attr__( '•••••••• saved — leave blank to keep', 'bw-2checkout-pricing' ) : esc_attr__( 'paste your Secret Key', 'bw-2checkout-pricing' ); ?>" />
								<p class="description"><?php esc_html_e( 'From 2Checkout: Integrations → Webhooks & API. Stored write-only and never shown again. Leave blank to keep the saved value.', 'bw-2checkout-pricing' ); ?></p>
							<?php endif; ?>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_checkout_base"><?php esc_html_e( 'Checkout base URL', 'bw-2checkout-pricing' ); ?></label></th>
						<td>
							<input type="text" id="bw2cp_checkout_base" name="<?php echo esc_attr( $name ); ?>[checkout_base]" value="<?php echo esc_attr( $s['checkout_base'] ); ?>" class="regular-text" />
							<p class="description"><?php esc_html_e( 'ConvertPlus buy-link base, e.g. https://shop.copernic.com/checkout/buy', 'bw-2checkout-pricing' ); ?></p>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_tpl"><?php esc_html_e( 'Checkout template', 'bw-2checkout-pricing' ); ?></label></th>
						<td><input type="text" id="bw2cp_tpl" name="<?php echo esc_attr( $name ); ?>[checkout_tpl]" value="<?php echo esc_attr( $s['checkout_tpl'] ); ?>" class="regular-text" /></td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_default_currency"><?php esc_html_e( 'Default currency', 'bw-2checkout-pricing' ); ?></label></th>
						<td><input type="text" id="bw2cp_default_currency" name="<?php echo esc_attr( $name ); ?>[default_currency]" value="<?php echo esc_attr( $s['default_currency'] ); ?>" class="small-text" /></td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_currencies"><?php esc_html_e( 'Currencies (selector)', 'bw-2checkout-pricing' ); ?></label></th>
						<td>
							<input type="text" id="bw2cp_currencies" name="<?php echo esc_attr( $name ); ?>[currencies]" value="<?php echo esc_attr( $s['currencies'] ); ?>" class="regular-text" />
							<p class="description"><?php esc_html_e( 'Comma-separated ISO codes to expose, e.g. USD,EUR,GBP,CAD.', 'bw-2checkout-pricing' ); ?></p>
						</td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_api_base"><?php esc_html_e( 'API base URL', 'bw-2checkout-pricing' ); ?></label></th>
						<td><input type="text" id="bw2cp_api_base" name="<?php echo esc_attr( $name ); ?>[api_base]" value="<?php echo esc_attr( $s['api_base'] ); ?>" class="regular-text" /></td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_cache_ttl"><?php esc_html_e( 'Cache TTL (seconds)', 'bw-2checkout-pricing' ); ?></label></th>
						<td><input type="number" id="bw2cp_cache_ttl" name="<?php echo esc_attr( $name ); ?>[cache_ttl]" value="<?php echo esc_attr( $s['cache_ttl'] ); ?>" class="small-text" min="0" /></td>
					</tr>
					<tr>
						<th scope="row"><?php esc_html_e( 'Test mode', 'bw-2checkout-pricing' ); ?></th>
						<td><label><input type="checkbox" name="<?php echo esc_attr( $name ); ?>[test_mode]" value="1" <?php checked( ! empty( $s['test_mode'] ) ); ?> /> <?php esc_html_e( 'Use 2Checkout test order flags (DOTEST=1) for cart links.', 'bw-2checkout-pricing' ); ?></label></td>
					</tr>
					<tr>
						<th scope="row"><label for="bw2cp_products"><?php esc_html_e( 'Products config (JSON)', 'bw-2checkout-pricing' ); ?></label></th>
						<td>
							<textarea id="bw2cp_products" name="<?php echo esc_attr( $name ); ?>[products_json]" rows="12" class="large-text code" spellcheck="false"><?php echo esc_textarea( $products_json ); ?></textarea>
							<p class="description">
								<?php esc_html_e( 'Maps widget selectors to a 2Checkout product code + option group/value codes. Example (verify value codes in sandbox):', 'bw-2checkout-pricing' ); ?>
							</p>
							<pre style="max-width:800px;overflow:auto;background:#f6f7f7;padding:8px;">{
  "cds": {
    "label": "Copernic Desktop &amp; Cloud Search",
    "product_code": "3WL7JRHV69",
    "selectors": [
      {"group": "EDITION_2", "label": "Edition", "type": "select",
       "values": [{"code":"basic","label":"Basic"},{"code":"advanced","label":"Advanced"},{"code":"elite","label":"Elite"}]},
      {"group": "TERM", "label": "Term", "type": "select",
       "values": [{"code":"1Y","label":"1 Year"},{"code":"2Y","label":"2 Years"},{"code":"3Y","label":"3 Years"}]},
      {"group": "users", "label": "Users", "type": "number", "min": 1, "default": 1}
    ]
  }
}</pre>
						</td>
					</tr>
				</table>
				<?php submit_button(); ?>
			</form>

			<hr />
			<h2><?php esc_html_e( 'Test connection', 'bw-2checkout-pricing' ); ?></h2>
			<p class="description"><?php esc_html_e( 'Makes one authenticated API call (list products) to confirm the credentials work.', 'bw-2checkout-pricing' ); ?></p>
			<form method="post" action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>">
				<input type="hidden" name="action" value="bw_2checkout_pricing_test" />
				<?php wp_nonce_field( 'bw_2checkout_pricing_test' ); ?>
				<?php submit_button( __( 'Test connection', 'bw-2checkout-pricing' ), 'secondary', 'submit', false ); ?>
			</form>
		</div>
		<?php
	}

	public function handle_test_connection() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Insufficient permissions.', 'bw-2checkout-pricing' ) );
		}
		check_admin_referer( 'bw_2checkout_pricing_test' );

		$client = new BW_2Checkout_Pricing_Client();
		if ( ! $client->is_configured() ) {
			$result = array(
				'ok'  => false,
				'msg' => __( 'No credentials set yet — enter the Merchant Code and Secret Key first.', 'bw-2checkout-pricing' ),
			);
		} else {
			$res = $client->get_products();
			if ( is_wp_error( $res ) ) {
				$result = array(
					'ok'  => false,
					'msg' => sprintf( '%s [%s]', $res->get_error_message(), $res->get_error_code() ),
				);
			} else {
				$count  = 0;
				if ( isset( $res['Items'] ) && is_array( $res['Items'] ) ) {
					$count = count( $res['Items'] );
				} elseif ( is_array( $res ) ) {
					$count = count( $res );
				}
				$result = array(
					'ok'  => true,
					'msg' => sprintf(
						/* translators: %d: number of products returned */
						__( 'Success — API reachable. Products returned: %d', 'bw-2checkout-pricing' ),
						$count
					),
				);
			}
		}

		set_transient( 'bw_2checkout_pricing_test_' . get_current_user_id(), $result, 60 );
		wp_safe_redirect( add_query_arg( 'page', self::PAGE, admin_url( 'options-general.php' ) ) );
		exit;
	}

	public function maybe_render_test_notice() {
		$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
		if ( self::PAGE !== $page ) {
			return;
		}
		$key    = 'bw_2checkout_pricing_test_' . get_current_user_id();
		$result = get_transient( $key );
		if ( ! $result ) {
			return;
		}
		delete_transient( $key );
		$class = ! empty( $result['ok'] ) ? 'notice-success' : 'notice-error';
		printf(
			'<div class="notice %1$s is-dismissible"><p>%2$s</p></div>',
			esc_attr( $class ),
			esc_html( $result['msg'] )
		);
	}
}
