<?php
/**
 * Shared Square connection settings (WooCommerce + Contact Form 7).
 *
 * @package SHC4WC
 */

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

class SHC4WC_Connection_Settings {
	private static $instance = null;

	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {
		add_action( 'admin_menu', array( $this, 'register_menu' ) );
		add_action( 'admin_init', array( $this, 'register_settings' ) );
		add_action( 'admin_notices', array( $this, 'admin_notice' ) );
	}

	public static function page_slug() {
		return 'payments-square-connect';
	}

	public static function page_url( $status = '' ) {
		$args = array();
		if ( $status ) {
			$args['shc4wc_status'] = $status;
		}
		return SHC4WC_Admin_Menu::page_url( SHC4WC_Admin_Menu::CONNECT_SLUG, $args );
	}

	public function register_menu() {
		SHC4WC_Admin_Menu::register_parent_menu();

		add_submenu_page(
			SHC4WC_Admin_Menu::MENU_SLUG,
			__( 'Payments Square Connect', 'payments-connect-square' ),
			__( 'Payments Square Connect', 'payments-connect-square' ),
			'manage_options',
			SHC4WC_Admin_Menu::CONNECT_SLUG,
			array( $this, 'render_page' )
		);
	}

	public function register_settings() {
		register_setting(
			'shc4wc_connection',
			'woocommerce_shc4wc_settings',
			array(
				'type'              => 'array',
				'sanitize_callback' => array( $this, 'sanitize_settings' ),
			)
		);
	}

	public function sanitize_settings( $input ) {
		$current = SHC4WC_Plugin::get_settings();
		$merged  = is_array( $current ) ? $current : array();
		if ( ! is_array( $input ) ) {
			return $merged;
		}
		$keys = array(
			'environment',
			'location_id',
			'debug',
		);
		foreach ( $keys as $key ) {
			if ( array_key_exists( $key, $input ) ) {
				$merged[ $key ] = $input[ $key ];
			}
		}
		return $merged;
	}

	public function admin_notice() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		$page = (string) filter_input( INPUT_GET, 'page', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
		if ( self::page_slug() !== $page ) {
			return;
		}

		static $shown_statuses = array();

		$status = (string) filter_input( INPUT_GET, 'shc4wc_status', FILTER_SANITIZE_FULL_SPECIAL_CHARS );
		if ( '' === $status || isset( $shown_statuses[ $status ] ) ) {
			return;
		}

		$map = array(
			'connected'                       => array( 'success', __( 'Square connected successfully.', 'payments-connect-square' ) ),
			'disconnected'                    => array( 'success', __( 'Square disconnected.', 'payments-connect-square' ) ),
			'missing_client_id'               => array( 'error', __( 'Client ID not found in credentials JSON for selected environment.', 'payments-connect-square' ) ),
			'oauth_denied'                    => array( 'error', __( 'Square authorization denied by user.', 'payments-connect-square' ) ),
			'oauth_state_error'               => array( 'error', __( 'OAuth state validation failed.', 'payments-connect-square' ) ),
			'oauth_request_failed'            => array( 'error', __( 'Could not connect to Square token endpoint.', 'payments-connect-square' ) ),
			'oauth_exchange_failed'           => array( 'error', __( 'Square token exchange failed.', 'payments-connect-square' ) ),
			'oauth_locations_failed'          => array( 'error', __( 'Access token received, but locations could not be fetched. Check permissions and retry.', 'payments-connect-square' ) ),
			'oauth_worker_misconfigured'      => array( 'error', __( 'Square login could not start. This site could not register with the OAuth service or the connection key was not saved. Enable Debug Log below and try again to see technical details.', 'payments-connect-square' ) ),
			'worker_register_invalid_base'    => array( 'error', __( 'Worker base URL must start with https://.', 'payments-connect-square' ) ),
			'worker_register_failed'          => array( 'error', __( 'Could not register this site with the OAuth service. Enable Debug Log below and try again to see technical details.', 'payments-connect-square' ) ),
			'worker_register_secret_required' => array(
				'error',
				__(
					'The OAuth Worker requires a registration secret. Set oauth_worker_registration_secret in shc4wc-host-config.php to the same value as Cloudflare secret REGISTRATION_SECRET - or remove REGISTRATION_SECRET from the Worker for open registration.',
					'payments-connect-square'
				),
			),
			'worker_register_unreachable'     => array(
				'error',
				__( 'Could not reach the OAuth Worker (network error). Check the Worker URL, firewall, and PHP SSL.', 'payments-connect-square' ),
			),
			'worker_register_bad_home_url'    => array(
				'error',
				__( 'The Worker rejected your site URL. In Settings -> General, set WordPress Address and Site Address to a full URL starting with http:// or https://.', 'payments-connect-square' ),
			),
			'worker_registered'               => array( 'success', __( 'Store registered. You can connect Payments Square Connect.', 'payments-connect-square' ) ),
			'oauth_claim_failed'              => array( 'error', __( 'Could not complete OAuth with the Worker (claim failed or session expired). Try connecting again.', 'payments-connect-square' ) ),
		);

		if ( ! isset( $map[ $status ] ) ) {
			return;
		}

		$shown_statuses[ $status ] = true;
		list( $type, $message )    = $map[ $status ];
		printf( '<div class="notice notice-%1$s"><p>%2$s</p>', esc_attr( $type ), esc_html( $message ) );
		self::render_admin_diagnostics_notice();
		echo '</div>';
	}

	/**
	 * Show last Worker/connect failure details when Debug Log is enabled.
	 */
	public static function render_admin_diagnostics_notice() {
		$settings = SHC4WC_Plugin::get_settings();
		if ( empty( $settings['debug'] ) || 'yes' !== $settings['debug'] ) {
			return;
		}

		$diag = SHC4WC_Plugin::get_admin_diagnostics();
		if ( empty( $diag ) ) {
			return;
		}

		$lines = array();
		if ( ! empty( $diag['context'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: internal context label. */
				__( 'Step: %s', 'payments-connect-square' ),
				(string) $diag['context']
			);
		}
		if ( ! empty( $diag['worker_error'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: worker error code. */
				__( 'Worker error: %s', 'payments-connect-square' ),
				(string) $diag['worker_error']
			);
		}
		if ( ! empty( $diag['transport_error'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: PHP HTTP transport error. */
				__( 'Network error: %s', 'payments-connect-square' ),
				(string) $diag['transport_error']
			);
		}
		if ( ! empty( $diag['http_code'] ) ) {
			$lines[] = sprintf(
				/* translators: %d: HTTP status code. */
				__( 'HTTP status: %d', 'payments-connect-square' ),
				(int) $diag['http_code']
			);
		}
		if ( ! empty( $diag['raw_snippet'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: short response body. */
				__( 'Response: %s', 'payments-connect-square' ),
				(string) $diag['raw_snippet']
			);
		}
		if ( isset( $diag['site_key_set'] ) ) {
			$lines[] = $diag['site_key_set']
				? __( 'Connection key: saved', 'payments-connect-square' )
				: __( 'Connection key: missing', 'payments-connect-square' );
		}
		if ( ! empty( $diag['worker_base'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: worker URL. */
				__( 'Worker: %s', 'payments-connect-square' ),
				(string) $diag['worker_base']
			);
		}
		if ( ! empty( $diag['site_url'] ) ) {
			$lines[] = sprintf(
				/* translators: %s: WordPress site URL. */
				__( 'Site URL sent: %s', 'payments-connect-square' ),
				(string) $diag['site_url']
			);
		}

		if ( empty( $lines ) ) {
			return;
		}

		echo '<p><strong>' . esc_html__( 'Technical details', 'payments-connect-square' ) . '</strong></p><ul style="list-style:disc;margin-left:1.5em;">';
		foreach ( $lines as $line ) {
			echo '<li>' . esc_html( $line ) . '</li>';
		}
		echo '</ul>';
	}

	public function render_page() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}
		$settings = SHC4WC_Plugin::get_settings();
		$fields   = $this->get_connection_fields();
		?>
		<div class="wrap">
			<h1><?php esc_html_e( 'Payments Square Connect', 'payments-connect-square' ); ?></h1>
			<p><?php esc_html_e( 'Set up Payments Square Connect once here. WooCommerce checkout and Contact Form 7 both use this connection when those plugins are active.', 'payments-connect-square' ); ?></p>
			<form method="post" action="options.php">
				<?php settings_fields( 'shc4wc_connection' ); ?>
				<table class="form-table" role="presentation">
					<?php
					foreach ( $fields as $key => $field ) {
						$this->render_field_row( $key, $field, $settings );
					}
					?>
				</table>
				<?php submit_button( __( 'Save connection settings', 'payments-connect-square' ) ); ?>
			</form>
			<?php if ( class_exists( 'WooCommerce' ) ) : ?>
				<p>
					<a href="<?php echo esc_url( admin_url( 'admin.php?page=wc-settings&tab=checkout&section=shc4wc' ) ); ?>">
						<?php esc_html_e( 'WooCommerce checkout display settings', 'payments-connect-square' ); ?>
					</a>
				</p>
			<?php endif; ?>
			<p>
				<a href="<?php echo esc_url( SHC4WC_Admin_Menu::page_url( SHC4WC_Admin_Menu::CHECKOUT_SLUG ) ); ?>">
					<?php esc_html_e( 'Checkout Settings (Square hosted checkout)', 'payments-connect-square' ); ?>
				</a>
				|
				<a href="<?php echo esc_url( SHC4WC_Admin_Menu::page_url( SHC4WC_Admin_Menu::SUBSCRIPTIONS_SLUG ) ); ?>">
					<?php esc_html_e( 'Subscription Plans', 'payments-connect-square' ); ?>
				</a>
				|
				<a href="<?php echo esc_url( SHC4WC_Admin_Menu::page_url( SHC4WC_Admin_Menu::SUPPORT_SLUG ) ); ?>">
					<?php esc_html_e( 'Support', 'payments-connect-square' ); ?>
				</a>
			</p>
		</div>
		<?php
	}

	private function get_connection_fields() {
		$location_options = $this->get_location_options();
		$has_oauth        = SHC4WC_Plugin::has_oauth_connection();

		$fields = array(
			'environment' => array(
				'title'   => __( 'Environment', 'payments-connect-square' ),
				'type'    => 'select',
				'options' => array(
					'sandbox' => __( 'Sandbox', 'payments-connect-square' ),
					'live'    => __( 'Live', 'payments-connect-square' ),
				),
			),
			'shc4wc_square_connect_title' => array(
				'title'       => __( 'Square account', 'payments-connect-square' ),
				'type'        => 'title',
				'description' => __( 'Choose Sandbox or Live above, then connect your Square account. Setup runs automatically in the background.', 'payments-connect-square' ),
			),
			'oauth_actions'               => array(
				'title' => __( 'Payments Square Connect', 'payments-connect-square' ),
				'type'  => 'shc4wc_oauth_actions',
			),
		);

		$fields['location_id'] = array(
			'title'       => __( 'Square Location', 'payments-connect-square' ),
			'type'        => 'select',
			'options'     => $location_options,
			'description' => $has_oauth ? $this->get_location_usage_description() : __( 'Set up Payments Square Connect first.', 'payments-connect-square' ),
		);
		$fields['debug']       = array(
			'title' => __( 'Debug Log', 'payments-connect-square' ),
			'type'  => 'checkbox',
			'label' => __( 'Enable logging', 'payments-connect-square' ),
		);
		$fields['webhook_url'] = array(
			'title' => __( 'Webhook URL', 'payments-connect-square' ),
			'type'  => 'shc4wc_webhook_url',
		);

		return $fields;
	}

	private function get_location_usage_description() {
		$parts = array();
		if ( class_exists( 'WooCommerce' ) ) {
			$parts[] = __( 'WooCommerce checkout', 'payments-connect-square' );
		}
		if ( defined( 'WPCF7_VERSION' ) || class_exists( 'WPCF7' ) ) {
			$parts[] = __( 'Contact Form 7 payments', 'payments-connect-square' );
		}
		if ( empty( $parts ) ) {
			return __( 'Used for Square payments on this site.', 'payments-connect-square' );
		}
		return sprintf(
			/* translators: %s: comma-separated list of integrations. */
			__( 'Used for %s.', 'payments-connect-square' ),
			implode( ', ', $parts )
		);
	}

	private function get_location_options() {
		$locations = SHC4WC_Plugin::get_locations();
		if ( empty( $locations ) ) {
			return array(
				'' => __( 'Use Payments Square Connect to load locations', 'payments-connect-square' ),
			);
		}
		$options = array( '' => __( 'Select a location', 'payments-connect-square' ) );
		foreach ( $locations as $location ) {
			if ( empty( $location['id'] ) ) {
				continue;
			}
			$name                       = ! empty( $location['name'] ) ? $location['name'] : $location['id'];
			$options[ $location['id'] ] = sprintf( '%s (%s)', $name, $location['id'] );
		}
		return $options;
	}

	private function render_field_row( $key, $field, $settings ) {
		$type  = isset( $field['type'] ) ? $field['type'] : 'text';
		$title = isset( $field['title'] ) ? $field['title'] : $key;
		$value = isset( $settings[ $key ] ) ? $settings[ $key ] : '';

		if ( 'title' === $type ) {
			echo '<tr><td colspan="2"><h2 class="title">' . esc_html( $title ) . '</h2>';
			if ( ! empty( $field['description'] ) ) {
				echo '<p class="description">' . esc_html( $field['description'] ) . '</p>';
			}
			echo '</td></tr>';
			return;
		}

		if ( in_array( $type, array( 'shc4wc_oauth_actions', 'shc4wc_worker_register', 'shc4wc_webhook_url' ), true ) ) {
			if ( 'shc4wc_oauth_actions' === $type ) {
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo self::render_oauth_actions_row( $title );
				return;
			}
			if ( 'shc4wc_webhook_url' === $type ) {
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
				echo self::render_webhook_url_row( $title );
				return;
			}
			if ( 'shc4wc_worker_register' === $type && class_exists( 'SHC4WC_Gateway' ) ) {
				$gateway = new SHC4WC_Gateway();
				if ( method_exists( $gateway, 'generate_shc4wc_worker_register_html' ) ) {
					// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
					echo $gateway->generate_shc4wc_worker_register_html( $key, $field );
					return;
				}
			}
		}

		echo '<tr><th scope="row"><label for="shc4wc_' . esc_attr( $key ) . '">' . esc_html( $title ) . '</label></th><td>';

		if ( 'select' === $type ) {
			echo '<select name="woocommerce_shc4wc_settings[' . esc_attr( $key ) . ']" id="shc4wc_' . esc_attr( $key ) . '">';
			foreach ( (array) $field['options'] as $opt_key => $label ) {
				printf(
					'<option value="%1$s" %2$s>%3$s</option>',
					esc_attr( $opt_key ),
					selected( (string) $value, (string) $opt_key, false ),
					esc_html( $label )
				);
			}
			echo '</select>';
		} elseif ( 'checkbox' === $type ) {
			printf(
				'<label><input type="checkbox" name="woocommerce_shc4wc_settings[%1$s]" id="shc4wc_%1$s" value="yes" %2$s /> %3$s</label>',
				esc_attr( $key ),
				checked( 'yes', (string) $value, false ),
				esc_html( isset( $field['label'] ) ? $field['label'] : '' )
			);
		} elseif ( 'password' === $type ) {
			printf(
				'<input type="password" class="regular-text" name="woocommerce_shc4wc_settings[%1$s]" id="shc4wc_%1$s" value="%2$s" autocomplete="new-password" />',
				esc_attr( $key ),
				esc_attr( (string) $value )
			);
		} else {
			printf(
				'<input type="text" class="regular-text" name="woocommerce_shc4wc_settings[%1$s]" id="shc4wc_%1$s" value="%2$s" />',
				esc_attr( $key ),
				esc_attr( (string) $value )
			);
		}

		if ( ! empty( $field['description'] ) ) {
			echo '<p class="description">' . esc_html( $field['description'] ) . '</p>';
		}
		echo '</td></tr>';
	}

	/**
	 * Connect / Disconnect Square buttons (no WooCommerce dependency).
	 *
	 * @param string $title Field label.
	 * @return string
	 */
	public static function render_oauth_actions_row( $title ) {
		$connect   = wp_nonce_url( admin_url( 'admin-post.php?action=shc4wc_oauth_start' ), 'shc4wc_oauth_start' );
		$revoke    = wp_nonce_url( admin_url( 'admin-post.php?action=shc4wc_oauth_revoke' ), 'shc4wc_oauth_revoke' );
		$oauth     = SHC4WC_Plugin::get_oauth_data();
		$has_oauth = SHC4WC_Plugin::has_oauth_connection();
		$merch     = SHC4WC_Plugin::is_merchant_connect_ui();

		$html  = '<tr valign="top">';
		$html .= '<th scope="row" class="titledesc">' . esc_html( $title ) . '</th>';
		$html .= '<td class="forminp">';
		if ( $has_oauth ) {
			$html .= '<a class="button" href="' . esc_url( $revoke ) . '">' . esc_html__( 'Disconnect Square', 'payments-connect-square' ) . '</a>';
		} else {
			$html .= '<a class="button button-primary" href="' . esc_url( $connect ) . '">' . esc_html__( 'Payments Square Connect', 'payments-connect-square' ) . '</a>';
		}

		if ( ! empty( $oauth['expires_at'] ) ) {
			$html .= '<p><strong>' . esc_html__( 'Connection renews before:', 'payments-connect-square' ) . '</strong> ' . esc_html( $oauth['expires_at'] ) . '</p>';
		}
		if ( ! $has_oauth ) {
			$html .= '<p>' . esc_html(
				$merch
					? __( 'Not connected yet. Click the button to sign in with Square.', 'payments-connect-square' )
					: __( 'Connection status: Not connected. Connect and save selected location.', 'payments-connect-square' )
			) . '</p>';
		}
		$html .= '</td></tr>';

		return $html;
	}

	/**
	 * Read-only webhook URL for Square Developer Dashboard.
	 *
	 * @param string $title Field label.
	 * @return string
	 */
	public static function render_webhook_url_row( $title ) {
		$url = esc_url( SHC4WC_Plugin::public_api_url( 'shc4wc_webhook' ) );

		$html  = '<tr valign="top">';
		$html .= '<th scope="row" class="titledesc">' . esc_html( $title ) . '</th>';
		$html .= '<td class="forminp"><code>' . esc_html( $url ) . '</code></td>';
		$html .= '</tr>';

		return $html;
	}
}
