<?php

/**
 * Settings page for Checkout Shield configuration.
 *
 * @package Carticy\CheckoutShield\Admin
 */
declare (strict_types = 1);
namespace Carticy\CheckoutShield\Admin;

use Carticy\CheckoutShield\Services\WhitelistService;
if ( !defined( 'ABSPATH' ) ) {
    exit;
}
/**
 * Handles the plugin settings page in WooCommerce.
 */
final class SettingsPage {
    /**
     * Whitelist service.
     *
     * @var WhitelistService
     */
    private WhitelistService $whitelist_service;

    /**
     * Constructor.
     *
     * @param WhitelistService $whitelist_service Whitelist service instance.
     */
    public function __construct( WhitelistService $whitelist_service ) {
        $this->whitelist_service = $whitelist_service;
    }

    /**
     * Register hooks.
     */
    public function register() : void {
        add_filter( 'woocommerce_get_sections_advanced', array($this, 'add_section') );
        add_filter(
            'woocommerce_get_settings_advanced',
            array($this, 'add_settings'),
            10,
            2
        );
        add_action( 'woocommerce_admin_field_carticy_checkout_shield_api_keys', array($this, 'render_api_keys_field') );
        add_action( 'woocommerce_update_options_advanced_checkout_shield', array($this, 'save_settings') );
        add_action( 'admin_enqueue_scripts', array($this, 'enqueue_admin_assets') );
        add_action( 'wp_ajax_carticy_checkout_shield_generate_api_key', array($this, 'ajax_generate_api_key') );
        add_action( 'wp_ajax_carticy_checkout_shield_delete_api_key', array($this, 'ajax_delete_api_key') );
    }

    /**
     * Add our section to WooCommerce Advanced settings.
     *
     * @param array $sections Existing sections.
     * @return array
     */
    public function add_section( array $sections ) : array {
        $sections['checkout_shield'] = __( 'Checkout Shield', 'carticy-checkout-shield-for-woocommerce' );
        return $sections;
    }

    /**
     * Add settings to our section.
     *
     * @param array  $settings        Existing settings.
     * @param string $current_section Current section ID.
     * @return array
     */
    public function add_settings( array $settings, string $current_section ) : array {
        if ( 'checkout_shield' !== $current_section ) {
            return $settings;
        }
        // Get current IPs as text for the textarea.
        $whitelisted_ips = $this->whitelist_service->get_whitelisted_ips();
        $ips_text = implode( "\n", $whitelisted_ips );
        $plugin_settings = array(
            array(
                'title' => __( 'Checkout Shield Settings', 'carticy-checkout-shield-for-woocommerce' ),
                'type'  => 'title',
                'desc'  => __( 'Protect your checkout from card testing attacks and automated bots.', 'carticy-checkout-shield-for-woocommerce' ),
                'id'    => 'carticy_checkout_shield_section',
            ),
            array(
                'title'   => __( 'Enable Protection', 'carticy-checkout-shield-for-woocommerce' ),
                'desc'    => __( 'Enable checkout protection', 'carticy-checkout-shield-for-woocommerce' ),
                'id'      => 'carticy_checkout_shield_enabled',
                'default' => 'yes',
                'type'    => 'checkbox',
            ),
            array(
                'title'    => __( 'Protection Mode', 'carticy-checkout-shield-for-woocommerce' ),
                'desc'     => __( 'Learning: Monitors traffic without blocking (use to test). Permissive: Only blocks requests missing both security token AND session (very lenient). Balanced: Blocks requests missing security token (recommended). Strict: Blocks if token is missing OR no active shopping session.', 'carticy-checkout-shield-for-woocommerce' ),
                'id'       => 'carticy_checkout_shield_mode',
                'default'  => 'balanced',
                'type'     => 'select',
                'class'    => 'wc-enhanced-select',
                'options'  => array(
                    'learning'   => __( 'Learning - Monitor only, never block (for testing)', 'carticy-checkout-shield-for-woocommerce' ),
                    'permissive' => __( 'Permissive - Block only obvious bots (very lenient)', 'carticy-checkout-shield-for-woocommerce' ),
                    'balanced'   => __( 'Balanced - Block suspicious requests (recommended)', 'carticy-checkout-shield-for-woocommerce' ),
                    'strict'     => __( 'Strict - Maximum protection (may have false positives)', 'carticy-checkout-shield-for-woocommerce' ),
                ),
                'desc_tip' => true,
            ),
            array(
                'title'    => __( 'Proxy Support', 'carticy-checkout-shield-for-woocommerce' ),
                'desc'     => __( 'Trust proxy headers for IP detection', 'carticy-checkout-shield-for-woocommerce' ),
                'desc_tip' => __( 'Enable ONLY if your site is behind Cloudflare, a load balancer, or reverse proxy. When enabled, the plugin reads X-Forwarded-For and similar headers to detect the real visitor IP. Leave disabled for direct connections to prevent IP spoofing.', 'carticy-checkout-shield-for-woocommerce' ),
                'id'       => 'carticy_checkout_shield_proxy_support',
                'default'  => 'no',
                'type'     => 'checkbox',
            ),
            array(
                'type' => 'sectionend',
                'id'   => 'carticy_checkout_shield_section',
            ),
            array(
                'title' => __( 'IP Whitelist', 'carticy-checkout-shield-for-woocommerce' ),
                'type'  => 'title',
                'desc'  => __( 'IP addresses that bypass all protection. Useful for internal testing, staging servers, or trusted payment processor IPs. Supports CIDR notation (e.g., 192.168.1.0/24).', 'carticy-checkout-shield-for-woocommerce' ),
                'id'    => 'carticy_checkout_shield_whitelist_section',
            ),
            array(
                'title'             => __( 'Whitelisted IPs', 'carticy-checkout-shield-for-woocommerce' ),
                'desc'              => __( 'Enter one IP address or CIDR range per line.', 'carticy-checkout-shield-for-woocommerce' ),
                'id'                => 'carticy_checkout_shield_whitelisted_ips_text',
                'type'              => 'textarea',
                'default'           => '',
                'value'             => $ips_text,
                'css'               => 'width: 400px; height: 120px;',
                'placeholder'       => "192.168.1.100\n10.0.0.0/8",
                'desc_tip'          => true,
                'custom_attributes' => array(
                    'rows' => 6,
                ),
            ),
            array(
                'type' => 'sectionend',
                'id'   => 'carticy_checkout_shield_whitelist_section',
            ),
            array(
                'title' => __( 'API Keys', 'carticy-checkout-shield-for-woocommerce' ),
                'type'  => 'title',
                'desc'  => __( 'Only needed for headless or custom checkout implementations. Standard WooCommerce checkout does not require API keys. Requests with a valid X-CCS-Key header bypass protection.', 'carticy-checkout-shield-for-woocommerce' ),
                'id'    => 'carticy_checkout_shield_api_keys_section',
            ),
            array(
                'type' => 'carticy_checkout_shield_api_keys',
                'id'   => 'carticy_checkout_shield_api_keys_display',
            ),
            array(
                'type' => 'sectionend',
                'id'   => 'carticy_checkout_shield_api_keys_section',
            )
        );
        // Upsell section for free users (kept in free version — uses is_paying, not is__premium_only).
        if ( !carticy_checkoutshield_fs()->is_paying() ) {
            $plugin_settings[] = array(
                'title' => __( 'Want more control?', 'carticy-checkout-shield-for-woocommerce' ),
                'type'  => 'title',
                'desc'  => sprintf( 
                    /* translators: %s: upgrade link */
                    __( 'Checkout Shield Pro gives you smart logging, automatic CDN detection, stronger permissive mode, checkout details in logs, and a customer blocklist. %s', 'carticy-checkout-shield-for-woocommerce' ),
                    '<a href="' . esc_url( carticy_checkoutshield_fs()->get_upgrade_url() ) . '">' . esc_html__( 'Upgrade to Pro &rarr;', 'carticy-checkout-shield-for-woocommerce' ) . '</a>'
                 ),
                'id'    => 'carticy_checkout_shield_upsell_section',
            );
            $plugin_settings[] = array(
                'type' => 'sectionend',
                'id'   => 'carticy_checkout_shield_upsell_section',
            );
        }
        return $plugin_settings;
    }

    /**
     * Render the API keys management field.
     *
     * @param array $value Field value configuration.
     */
    public function render_api_keys_field( array $value ) : void {
        $api_keys = $this->whitelist_service->get_api_keys();
        ?>
		<tr valign="top">
			<th scope="row" class="titledesc">
				<label><?php 
        esc_html_e( 'API Keys', 'carticy-checkout-shield-for-woocommerce' );
        ?></label>
			</th>
			<td class="forminp">
				<div id="ccs-api-keys-container">
					<table class="widefat ccs-api-keys-table" style="max-width: 600px;">
						<thead>
							<tr>
								<th><?php 
        esc_html_e( 'Name', 'carticy-checkout-shield-for-woocommerce' );
        ?></th>
								<th><?php 
        esc_html_e( 'Created', 'carticy-checkout-shield-for-woocommerce' );
        ?></th>
								<th style="width: 80px;"><?php 
        esc_html_e( 'Actions', 'carticy-checkout-shield-for-woocommerce' );
        ?></th>
							</tr>
						</thead>
						<tbody id="ccs-api-keys-list">
							<?php 
        if ( empty( $api_keys ) ) {
            ?>
								<tr class="ccs-no-keys">
									<td colspan="3"><?php 
            esc_html_e( 'No API keys configured.', 'carticy-checkout-shield-for-woocommerce' );
            ?></td>
								</tr>
							<?php 
        } else {
            ?>
								<?php 
            foreach ( $api_keys as $key ) {
                ?>
									<tr data-hash="<?php 
                echo esc_attr( $key['hash'] );
                ?>">
										<td><?php 
                echo esc_html( ( !empty( $key['name'] ) ? $key['name'] : __( 'Unnamed', 'carticy-checkout-shield-for-woocommerce' ) ) );
                ?></td>
										<td><?php 
                echo esc_html( date_i18n( get_option( 'date_format' ), $key['created'] ) );
                ?></td>
										<td>
											<button type="button" class="button button-small ccs-delete-key" data-hash="<?php 
                echo esc_attr( $key['hash'] );
                ?>">
												<?php 
                esc_html_e( 'Delete', 'carticy-checkout-shield-for-woocommerce' );
                ?>
											</button>
										</td>
									</tr>
								<?php 
            }
            ?>
							<?php 
        }
        ?>
						</tbody>
					</table>
					<p style="margin-top: 10px;">
						<input type="text" id="ccs-new-key-name" placeholder="<?php 
        esc_attr_e( 'Key name (optional)', 'carticy-checkout-shield-for-woocommerce' );
        ?>" style="width: 200px;">
						<button type="button" class="button" id="ccs-generate-key">
							<?php 
        esc_html_e( 'Generate New Key', 'carticy-checkout-shield-for-woocommerce' );
        ?>
						</button>
					</p>
					<div id="ccs-new-key-display" style="display: none; margin-top: 10px; padding: 10px; background: #f0f6fc; border: 1px solid #0073aa; border-radius: 4px;">
						<p><strong><?php 
        esc_html_e( 'New API Key (copy now - shown only once):', 'carticy-checkout-shield-for-woocommerce' );
        ?></strong></p>
						<code id="ccs-new-key-value" style="display: block; padding: 8px; background: #fff; border: 1px solid #ddd; word-break: break-all;"></code>
					</div>
				</div>
				<?php 
        wp_nonce_field( 'ccs_api_key_nonce', 'ccs_api_key_nonce' );
        ?>
			</td>
		</tr>
		<?php 
    }

    /**
     * Detect if the current request is coming through a known proxy/CDN.
     *
     * @return string Detected proxy name or empty string.
     */
    public static function detect_proxy() : string {
        // phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
        if ( !empty( $_SERVER['HTTP_CF_CONNECTING_IP'] ) ) {
            return 'Cloudflare';
        }
        if ( !empty( $_SERVER['HTTP_X_SUCURI_CLIENTIP'] ) ) {
            return 'Sucuri';
        }
        if ( !empty( $_SERVER['HTTP_TRUE_CLIENT_IP'] ) ) {
            return 'Akamai';
        }
        if ( !empty( $_SERVER['HTTP_X_REAL_IP'] ) ) {
            return 'Reverse Proxy (X-Real-IP)';
        }
        if ( !empty( $_SERVER['HTTP_X_FORWARDED_FOR'] ) ) {
            return 'Proxy (X-Forwarded-For)';
        }
        // phpcs:enable WordPress.Security.ValidatedSanitizedInput.InputNotValidated
        return '';
    }

    /**
     * Get proxy detection description for settings display.
     *
     * @return string HTML description with detection result.
     */
    private function get_proxy_detection_desc() : string {
        $detected = self::detect_proxy();
        if ( $detected ) {
            return sprintf( '<strong style="color:#00a32a;">&#10003; %s</strong>', sprintf( 
                /* translators: %s: detected proxy/CDN name */
                esc_html__( 'Detected: %s', 'carticy-checkout-shield-for-woocommerce' ),
                esc_html( $detected )
             ) );
        }
        return esc_html__( 'No proxy/CDN detected on this request.', 'carticy-checkout-shield-for-woocommerce' );
    }

    /**
     * Render the blocklist management link field.
     *
     * @param array $value Field value configuration.
     */
    public function render_blocklist_link_field( array $value ) : void {
        $blocklist_url = admin_url( 'admin.php?page=ccs-blocklist' );
        ?>
		<tr valign="top">
			<th scope="row" class="titledesc"></th>
			<td class="forminp">
				<a href="<?php 
        echo esc_url( $blocklist_url );
        ?>" class="button">
					<?php 
        esc_html_e( 'View & Manage Blocklist', 'carticy-checkout-shield-for-woocommerce' );
        ?>
				</a>
				<p class="description" style="margin-top: 8px;">
					<?php 
        esc_html_e( 'You can also block customers directly from the order edit screen.', 'carticy-checkout-shield-for-woocommerce' );
        ?>
				</p>
			</td>
		</tr>
		<?php 
    }

    /**
     * Save settings with custom processing.
     */
    public function save_settings() : void {
        // Process IP whitelist from textarea to array.
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified by WooCommerce.
        if ( isset( $_POST['carticy_checkout_shield_whitelisted_ips_text'] ) ) {
            // phpcs:ignore WordPress.Security.NonceVerification.Missing
            $ips_text = sanitize_textarea_field( wp_unslash( $_POST['carticy_checkout_shield_whitelisted_ips_text'] ) );
            $ips = array_filter( array_map( 'trim', explode( "\n", $ips_text ) ) );
            // Validate each IP.
            $valid_ips = array();
            foreach ( $ips as $ip ) {
                $ip = sanitize_text_field( $ip );
                if ( $this->is_valid_ip_or_cidr( $ip ) ) {
                    $valid_ips[] = $ip;
                }
            }
            update_option( 'carticy_checkout_shield_whitelisted_ips', array_unique( $valid_ips ) );
        }
    }

    /**
     * Validate an IP address or CIDR notation.
     *
     * @param string $ip The IP or CIDR to validate.
     * @return bool
     */
    private function is_valid_ip_or_cidr( string $ip ) : bool {
        if ( strpos( $ip, '/' ) !== false ) {
            list( $subnet, $mask ) = explode( '/', $ip, 2 );
            return filter_var( $subnet, FILTER_VALIDATE_IP ) && is_numeric( $mask ) && $mask >= 0 && $mask <= 128;
        }
        return (bool) filter_var( $ip, FILTER_VALIDATE_IP );
    }

    /**
     * AJAX handler to generate a new API key.
     */
    public function ajax_generate_api_key() : void {
        check_ajax_referer( 'ccs_api_key_nonce', 'nonce' );
        if ( !current_user_can( 'manage_woocommerce' ) ) {
            wp_send_json_error( array(
                'message' => __( 'Permission denied.', 'carticy-checkout-shield-for-woocommerce' ),
            ) );
        }
        $name = ( isset( $_POST['name'] ) ? sanitize_text_field( wp_unslash( $_POST['name'] ) ) : '' );
        $key_data = $this->whitelist_service->generate_api_key( $name );
        wp_send_json_success( array(
            'key'     => $key_data['key'],
            'hash'    => $key_data['hash'],
            'name'    => $key_data['name'],
            'created' => date_i18n( get_option( 'date_format' ), $key_data['created'] ),
        ) );
    }

    /**
     * AJAX handler to delete an API key.
     */
    public function ajax_delete_api_key() : void {
        check_ajax_referer( 'ccs_api_key_nonce', 'nonce' );
        if ( !current_user_can( 'manage_woocommerce' ) ) {
            wp_send_json_error( array(
                'message' => __( 'Permission denied.', 'carticy-checkout-shield-for-woocommerce' ),
            ) );
        }
        $hash = ( isset( $_POST['hash'] ) ? sanitize_text_field( wp_unslash( $_POST['hash'] ) ) : '' );
        if ( empty( $hash ) ) {
            wp_send_json_error( array(
                'message' => __( 'Invalid key.', 'carticy-checkout-shield-for-woocommerce' ),
            ) );
        }
        $this->whitelist_service->remove_api_key( $hash );
        wp_send_json_success();
    }

    /**
     * Enqueue admin assets.
     *
     * @param string $hook Current admin page hook.
     */
    public function enqueue_admin_assets( string $hook ) : void {
        if ( 'woocommerce_page_wc-settings' !== $hook ) {
            return;
        }
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only.
        $section = ( isset( $_GET['section'] ) ? sanitize_text_field( wp_unslash( $_GET['section'] ) ) : '' );
        if ( 'checkout_shield' !== $section ) {
            return;
        }
        wp_add_inline_style( 'woocommerce_admin_styles', $this->get_inline_styles() );
        wp_add_inline_script( 'jquery', $this->get_inline_script() );
    }

    /**
     * Get inline CSS for the settings page.
     *
     * @return string
     */
    private function get_inline_styles() : string {
        return '
			.woocommerce table.form-table th {
				padding: 15px 10px 15px 0;
			}
			.woocommerce table.form-table td {
				padding: 10px 10px 10px 0;
			}
			.woocommerce table.form-table textarea {
				font-family: monospace;
				font-size: 13px;
			}
			table.widefat.ccs-api-keys-table {
				border-collapse: collapse;
				border: 1px solid #c3c4c7;
			}
			table.widefat.ccs-api-keys-table th,
			table.widefat.ccs-api-keys-table td {
				padding: 12px 16px !important;
				text-align: left;
				border-bottom: 1px solid #e1e1e1;
				width: auto !important;
				line-height: 1.4;
			}
			table.widefat.ccs-api-keys-table thead th {
				background: #f6f7f7;
				font-weight: 600;
				border-bottom: 1px solid #c3c4c7;
				padding: 14px 16px !important;
			}
			table.widefat.ccs-api-keys-table tbody tr:last-child td {
				border-bottom: none;
			}
			table.widefat.ccs-api-keys-table .ccs-no-keys td {
				color: #666;
				font-style: italic;
			}
		';
    }

    /**
     * Get inline JavaScript for API key management.
     *
     * @return string
     */
    private function get_inline_script() : string {
        return "\n\t\t\tjQuery(document).ready(function(\$) {\n\t\t\t\t// Generate new API key.\n\t\t\t\t\$('#ccs-generate-key').on('click', function() {\n\t\t\t\t\tvar name = \$('#ccs-new-key-name').val();\n\t\t\t\t\tvar nonce = \$('#ccs_api_key_nonce').val();\n\n\t\t\t\t\t\$.post(ajaxurl, {\n\t\t\t\t\t\taction: 'carticy_checkout_shield_generate_api_key',\n\t\t\t\t\t\tnonce: nonce,\n\t\t\t\t\t\tname: name\n\t\t\t\t\t}, function(response) {\n\t\t\t\t\t\tif (response.success) {\n\t\t\t\t\t\t\t// Show the new key.\n\t\t\t\t\t\t\t\$('#ccs-new-key-value').text(response.data.key);\n\t\t\t\t\t\t\t\$('#ccs-new-key-display').show();\n\n\t\t\t\t\t\t\t// Add row to table.\n\t\t\t\t\t\t\t\$('.ccs-no-keys').remove();\n\t\t\t\t\t\t\tvar row = '<tr data-hash=\"' + response.data.hash + '\">' +\n\t\t\t\t\t\t\t\t'<td>' + (response.data.name || 'Unnamed') + '</td>' +\n\t\t\t\t\t\t\t\t'<td>' + response.data.created + '</td>' +\n\t\t\t\t\t\t\t\t'<td><button type=\"button\" class=\"button button-small ccs-delete-key\" data-hash=\"' + response.data.hash + '\">Delete</button></td>' +\n\t\t\t\t\t\t\t\t'</tr>';\n\t\t\t\t\t\t\t\$('#ccs-api-keys-list').append(row);\n\n\t\t\t\t\t\t\t// Clear input.\n\t\t\t\t\t\t\t\$('#ccs-new-key-name').val('');\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert(response.data.message || 'Error generating key.');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\n\t\t\t\t// Delete API key.\n\t\t\t\t\$(document).on('click', '.ccs-delete-key', function() {\n\t\t\t\t\tif (!confirm('Are you sure you want to delete this API key?')) {\n\t\t\t\t\t\treturn;\n\t\t\t\t\t}\n\n\t\t\t\t\tvar hash = \$(this).data('hash');\n\t\t\t\t\tvar row = \$(this).closest('tr');\n\t\t\t\t\tvar nonce = \$('#ccs_api_key_nonce').val();\n\n\t\t\t\t\t\$.post(ajaxurl, {\n\t\t\t\t\t\taction: 'carticy_checkout_shield_delete_api_key',\n\t\t\t\t\t\tnonce: nonce,\n\t\t\t\t\t\thash: hash\n\t\t\t\t\t}, function(response) {\n\t\t\t\t\t\tif (response.success) {\n\t\t\t\t\t\t\trow.remove();\n\t\t\t\t\t\t\tif (\$('#ccs-api-keys-list tr').length === 0) {\n\t\t\t\t\t\t\t\t\$('#ccs-api-keys-list').append('<tr class=\"ccs-no-keys\"><td colspan=\"3\">No API keys configured.</td></tr>');\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\talert(response.data.message || 'Error deleting key.');\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t});\n\t\t";
    }

}
