<?php

namespace WeDevs\AppBridge\Integrations\WooCommerce;

use WeDevs\AppBridge\Core\AbstractSettingsSchema;
use WeDevs\AppBridge\Core\Auth\JwtAuth;
use WeDevs\AppBridge\Integrations\WooCommerce\Notifications\CustomerEventCatalog;

class SettingsSchema extends AbstractSettingsSchema {

	private LicenseManager $license_manager;

	public function __construct( LicenseManager $license_manager ) {
		$this->license_manager = $license_manager;
	}

	protected function slug(): string {
		return 'woocommerce';
	}

	protected function is_licensed(): bool {
		return $this->license_manager->get_license()->is_valid();
	}

	// ── WooCommerce-specific: extend app identity with JWT key + new arrival ──

	protected function app_identity_fields( array $settings ): array {
		return array_merge(
			[
				[
					'id'             => 'jwt_auth_secret_key',
					'type'           => 'field',
					'variant'        => 'text',
					'label'          => __( 'JWT Auth Secret Key', 'app-bridge' ),
					'section_id'     => 'app_identity',
					'dependency_key' => 'jwt_auth_secret_key',
					'value'          => (string) get_option( JwtAuth::SECRET_KEY_OPTION, '' ),
					'description'    => __( 'Secret key for JWT authentication.', 'app-bridge' ),
				],
			],
			parent::app_identity_fields( $settings ),
		);
	}

	// ── WooCommerce-specific pages ────────────────────────────────────────────

	protected function pages(): array {
		return [
			[
				'id'          => 'social-login',
				'type'        => 'page',
				'label'       => __( 'Social Login', 'app-bridge' ),
				'description' => __( 'Configure OAuth credentials for Facebook, Google, Twitter, LinkedIn, and Apple sign-in providers.', 'app-bridge' ),
				'icon'        => 'Users',
			],
			$this->sliders_page(),
		];
	}

	// Move the inherited provider-config section under the "Configuration" tab.
	protected function notification_provider_section(): array {
		return [
			'id'     => 'notification_provider',
			'type'   => 'section',
			'label'  => __( 'Provider Configuration', 'app-bridge' ),
			'tab_id' => 'configuration',
		];
	}

	// ── WooCommerce-specific sections ─────────────────────────────────────────

	protected function sections(): array {
		return [
			[
				'id'       => 'configuration',
				'type'     => 'tab',
				'label'    => __( 'Configuration', 'app-bridge' ),
				'page_id'  => $this->push_notifications_page_id(),
				'priority' => 10,
			],
			[
				'id'       => 'events',
				'type'     => 'tab',
				'label'    => __( 'Events', 'app-bridge' ),
				'page_id'  => $this->push_notifications_page_id(),
				'priority' => 20,
			],
			[
				'id'        => 'send-notifications',
				'type'      => 'tab',
				'label'     => __( 'Send Notifications', 'app-bridge' ),
				'page_id'   => $this->push_notifications_page_id(),
				'priority'  => 30,
				'hide_save' => true,
			],
			[
				'id' => 'pages_and_display',
				'type' => 'section',
				'label' => __( 'Pages & Display', 'app-bridge' ),
				'page_id' => 'general',
			],
			[
				'id'      => 'facebook',
				'type'    => 'section',
				'label'   => __( 'Facebook', 'app-bridge' ),
				'page_id' => 'social-login',
			],
			[
				'id'      => 'google',
				'type'    => 'section',
				'label'   => __( 'Google', 'app-bridge' ),
				'page_id' => 'social-login',
			],
			[
				'id'      => 'twitter',
				'type'    => 'section',
				'label'   => __( 'Twitter', 'app-bridge' ),
				'page_id' => 'social-login',
			],
			[
				'id'      => 'linkedin',
				'type'    => 'section',
				'label'   => __( 'LinkedIn', 'app-bridge' ),
				'page_id' => 'social-login',
			],
			[
				'id'      => 'apple',
				'type'    => 'section',
				'label'   => __( 'Apple', 'app-bridge' ),
				'page_id' => 'social-login',
			],
		];
	}

	// Drop the standalone "App Languages" section — language picker moves into
	// the "Pages & Display" section below.
	protected function languages_section(): array {
		return [];
	}

	protected function languages_fields( array $settings ): array {
		$saved_app_langs = $this->normalize_language_codes( $settings['app_languages'] ?? null );
		if ( empty( $saved_app_langs ) ) {
			$saved_app_langs = [ 'en' ];
		}

		return [
			[
				'id'             => 'app_languages',
				'type'           => 'field',
				'variant'        => 'multicheck',
				'label'          => __( 'App Languages', 'app-bridge' ),
				'section_id'     => 'pages_and_display',
				'dependency_key' => 'app_languages',
				'value'          => $saved_app_langs,
				'default'        => [ 'en' ],
				'options'        => $this->language_options(),
				'description'    => __( 'Languages available inside the mobile app.', 'app-bridge' ),
			],
			[
				'id'             => 'default_app_language',
				'type'           => 'field',
				'variant'        => 'select',
				'label'          => __( 'Default Language', 'app-bridge' ),
				'section_id'     => 'pages_and_display',
				'dependency_key' => 'default_app_language',
				'value'          => (string) ( $settings['default_app_language'] ?? 'en' ),
				'default'        => 'en',
				'options'        => $this->language_options(),
				'description'    => __( 'Language used by the mobile app on first launch.', 'app-bridge' ),
			],
		];
	}

	// ── WooCommerce-specific fields ───────────────────────────────────────────

	protected function fields( array $settings ): array {
		$page_options = $this->page_select_options();

		$social = get_option( 'app_bridge_social_api', [] );
		$social = is_array( $social ) ? $social : [];

		return array_merge(
			$this->pages_display_fields( $settings, $page_options ),
			$this->push_notification_event_sections(),
			$this->push_notification_event_fields( $settings ),
			$this->social_login_fields( $social ),
			[ $this->send_notification_form_field() ],
			[ $this->sliders_field() ],
		);
	}

	/**
	 * Custom field rendered by the `send_notification_form` variant. The
	 * pocket-store app intercepts the variant via applyFilters and renders
	 * the form component. `no_wrap` skips plugin-ui's card wrapper.
	 */
	private function send_notification_form_field(): array {
		return [
			'id'      => 'send_notification_form',
			'type'    => 'field',
			'variant' => 'send_notification_form',
			'tab_id'  => 'send-notifications',
			'no_wrap' => true,
			'display' => true,
		];
	}

	// ── Sanitization ──────────────────────────────────────────────────────────

	protected function sanitize( array $data ): array {
		$result = parent::sanitize_common( $data );

		// JWT secret is persisted to a dedicated wp_option in save(); skip here.

		if ( isset( $data['pages_and_display'] ) ) {
			$s                                   = $data['pages_and_display'];
			$result['display_sold_item_count']   = (bool) ( $s['display_sold_item_count'] ?? true );
			$result['about_us_page_id']          = absint( $s['about_us_page_id'] ?? 0 );
			$result['contact_us_page_id']        = absint( $s['contact_us_page_id'] ?? 0 );
			$result['privacy_policy_page_id']    = absint( $s['privacy_policy_page_id'] ?? 0 );
			if ( isset( $s['default_app_language'] ) ) {
				$result['default_app_language'] = sanitize_key( (string) $s['default_app_language'] );
			}
			if ( isset( $s['app_languages'] ) ) {
				$result['app_languages'] = $this->normalize_language_codes( $s['app_languages'] );
			}
		}

		$events_overrides = self::sanitize_push_events_data( $data, $this->customer_push_event_categories() );
		if ( ! empty( $events_overrides ) ) {
			$result['push_events'] = $events_overrides;
		}

		return $result;
	}

	/**
	 * Persists the shared JWT secret to its dedicated wp_option (single
	 * source for Pocket Store + Vendor App), then writes social login
	 * credentials to their legacy option key.
	 */
	public function save( array $data ): void {
		parent::save( $data );

		if ( isset( $data['app_identity']['jwt_auth_secret_key'] ) ) {
			update_option(
				JwtAuth::SECRET_KEY_OPTION,
				sanitize_text_field( (string) $data['app_identity']['jwt_auth_secret_key'] ),
				false
			);
		}

		// Social login fields arrive grouped by provider section id.
		$social_sections = [ 'facebook', 'google', 'twitter', 'linkedin', 'apple' ];
		$has_social      = false;
		foreach ( $social_sections as $provider ) {
			if ( isset( $data[ $provider ] ) ) {
				$has_social = true;
				break;
			}
		}

		if ( $has_social ) {
			$existing_social = get_option( 'app_bridge_social_api', [] );

			$map = [
				'facebook' => [
					'id'     => sanitize_text_field( $data['facebook']['fb_app_id'] ?? '' ),
					'secret' => sanitize_text_field( $data['facebook']['fb_app_secret'] ?? '' ),
				],
				'google'   => [
					'id'     => sanitize_text_field( $data['google']['google_client_id'] ?? '' ),
					'secret' => sanitize_text_field( $data['google']['google_client_secret'] ?? '' ),
				],
				'twitter'  => [
					'id'     => sanitize_text_field( $data['twitter']['twitter_api_key'] ?? '' ),
					'secret' => sanitize_text_field( $data['twitter']['twitter_api_secret'] ?? '' ),
				],
				'linkedin' => [
					'id'     => sanitize_text_field( $data['linkedin']['linkedin_client_id'] ?? '' ),
					'secret' => sanitize_text_field( $data['linkedin']['linkedin_client_secret'] ?? '' ),
				],
				'apple'    => [
					'id'          => sanitize_text_field( $data['apple']['apple_service_id'] ?? '' ),
					'team_id'     => sanitize_text_field( $data['apple']['apple_team_id'] ?? '' ),
					'key_id'      => sanitize_text_field( $data['apple']['apple_key_id'] ?? '' ),
					'key_content' => sanitize_textarea_field( $data['apple']['apple_key_content'] ?? '' ),
				],
			];

			// Only update providers that were included in the payload.
			foreach ( $social_sections as $provider ) {
				if ( isset( $data[ $provider ] ) ) {
					$existing_social[ $provider ] = $map[ $provider ];
				}
			}

			update_option( 'app_bridge_social_api', $existing_social, false );
		}
	}

	// ── Private field builders ────────────────────────────────────────────────

	private function pages_display_fields( array $s, array $page_options ): array {
		return [
			[
				'id' => 'about_us_page_id',
				'type' => 'field',
				'variant' => 'select',
				'label' => __( 'About Us Page', 'app-bridge' ),
				'section_id' => 'pages_and_display',
				'dependency_key' => 'about_us_page_id',
				'value' => (string) ( $s['about_us_page_id'] ?? '0' ),
				'options' => $page_options,
			],
			[
				'id' => 'contact_us_page_id',
				'type' => 'field',
				'variant' => 'select',
				'label' => __( 'Contact Us Page', 'app-bridge' ),
				'section_id' => 'pages_and_display',
				'dependency_key' => 'contact_us_page_id',
				'value' => (string) ( $s['contact_us_page_id'] ?? '0' ),
				'options' => $page_options,
			],
			[
				'id' => 'privacy_policy_page_id',
				'type' => 'field',
				'variant' => 'select',
				'label' => __( 'Privacy Policy Page', 'app-bridge' ),
				'section_id' => 'pages_and_display',
				'dependency_key' => 'privacy_policy_page_id',
				'value' => (string) ( $s['privacy_policy_page_id'] ?? '0' ),
				'options' => $page_options,
			],
			[
				'id' => 'display_sold_item_count',
				'type' => 'field',
				'variant' => 'switch',
				'label' => __( 'Display Sold Item Count', 'app-bridge' ),
				'section_id' => 'pages_and_display',
				'dependency_key' => 'display_sold_item_count',
				'value' => (bool) ( $s['display_sold_item_count'] ?? true ),
			],
		];
	}

	private function social_login_fields( array $social ): array {
		return [
			[
				'id' => 'fb_app_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'App ID', 'app-bridge' ),
				'section_id' => 'facebook',
				'dependency_key' => 'social_login.facebook.id',
				'value' => $social['facebook']['id'] ?? '',
			],
			[
				'id' => 'fb_app_secret',
				'type' => 'field',
				'variant' => 'show_hide',
				'label' => __( 'App Secret', 'app-bridge' ),
				'section_id' => 'facebook',
				'dependency_key' => 'social_login.facebook.secret',
				'value' => $social['facebook']['secret'] ?? '',
			],

			[
				'id' => 'google_client_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'Client ID', 'app-bridge' ),
				'section_id' => 'google',
				'dependency_key' => 'social_login.google.id',
				'value' => $social['google']['id'] ?? '',
			],
			[
				'id' => 'google_client_secret',
				'type' => 'field',
				'variant' => 'show_hide',
				'label' => __( 'Client Secret', 'app-bridge' ),
				'section_id' => 'google',
				'dependency_key' => 'social_login.google.secret',
				'value' => $social['google']['secret'] ?? '',
			],

			[
				'id' => 'twitter_api_key',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'API Key', 'app-bridge' ),
				'section_id' => 'twitter',
				'dependency_key' => 'social_login.twitter.id',
				'value' => $social['twitter']['id'] ?? '',
			],
			[
				'id' => 'twitter_api_secret',
				'type' => 'field',
				'variant' => 'show_hide',
				'label' => __( 'API Secret', 'app-bridge' ),
				'section_id' => 'twitter',
				'dependency_key' => 'social_login.twitter.secret',
				'value' => $social['twitter']['secret'] ?? '',
			],

			[
				'id' => 'linkedin_client_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'Client ID', 'app-bridge' ),
				'section_id' => 'linkedin',
				'dependency_key' => 'social_login.linkedin.id',
				'value' => $social['linkedin']['id'] ?? '',
			],
			[
				'id' => 'linkedin_client_secret',
				'type' => 'field',
				'variant' => 'show_hide',
				'label' => __( 'Client Secret', 'app-bridge' ),
				'section_id' => 'linkedin',
				'dependency_key' => 'social_login.linkedin.secret',
				'value' => $social['linkedin']['secret'] ?? '',
			],

			[
				'id' => 'apple_service_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'Service ID', 'app-bridge' ),
				'section_id' => 'apple',
				'dependency_key' => 'social_login.apple.id',
				'value' => $social['apple']['id'] ?? '',
			],
			[
				'id' => 'apple_team_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'Team ID', 'app-bridge' ),
				'section_id' => 'apple',
				'dependency_key' => 'social_login.apple.team_id',
				'value' => $social['apple']['team_id'] ?? '',
			],
			[
				'id' => 'apple_key_id',
				'type' => 'field',
				'variant' => 'text',
				'label' => __( 'Key ID', 'app-bridge' ),
				'section_id' => 'apple',
				'dependency_key' => 'social_login.apple.key_id',
				'value' => $social['apple']['key_id'] ?? '',
			],
			[
				'id' => 'apple_key_content',
				'type' => 'field',
				'variant' => 'textarea',
				'label' => __( 'Key Content', 'app-bridge' ),
				'section_id' => 'apple',
				'dependency_key' => 'social_login.apple.key_content',
				'value' => $social['apple']['key_content'] ?? '',
				'description' => __( 'Contents of the .p8 key file.', 'app-bridge' ),
			],
		];
	}

	private function page_select_options(): array {
		$pages = get_posts(
            [
				'post_type'   => 'page',
				'numberposts' => -1,
				'orderby'     => 'post_title',
				'order'       => 'asc',
			]
        );

		$options = [
			[
				'label' => __( '— Select —', 'app-bridge' ),
				'value' => '0',
			],
		];

		foreach ( ( $pages ? $pages : [] ) as $page ) {
			$options[] = [
				'label' => $page->post_title,
				'value' => (string) $page->ID,
			];
		}

		return $options;
	}

	// ── Push notification events (Customer App) ───────────────────────────────

	/**
	 * Catalog of Customer App push-notification events grouped by category.
	 *
	 * Sourced from {@see CustomerEventCatalog} so the dispatcher and the editor
	 * UI share one definition. Do not inline events here.
	 *
	 * @return array<string, array{label:string, description?:string, events:array<int, array<string, mixed>>}>
	 */
	private function customer_push_event_categories(): array {
		return CustomerEventCatalog::categories();
	}

	/**
	 * Emits one section per event category under the Events tab.
	 *
	 * @return array<int, array<string, mixed>>
	 */
	private function push_notification_event_sections(): array {
		$sections = [];
		$priority = 10;
		$first    = true;

		foreach ( $this->customer_push_event_categories() as $cat_id => $cat ) {
			$sections[] = [
				'id'          => 'events_' . $cat_id,
				'type'        => 'section',
				'label'       => $cat['label'],
				'description' => $cat['description'] ?? '',
				'tab_id'      => 'events',
				'priority'    => $priority,
				'collapsible' => true,
				'collapsed'   => ! $first,
			];
			$priority += 10;
			$first     = false;
		}

		return $sections;
	}

	/**
	 * Emits one custom `notification_event` field per event.
	 *
	 * The frontend (`NotificationEventField`) renders a compact, expandable
	 * card per event — toggle in the header, title + body revealed under a
	 * chevron. Each field's value is the full `{enabled, title, body}` shape
	 * keyed by event id, so on save the dispatcher reads it back unchanged.
	 *
	 * @param array<string, mixed> $settings Saved option values.
	 * @return array<int, array<string, mixed>>
	 */
	private function push_notification_event_fields( array $settings ): array {
		$saved_events = $settings['push_events'] ?? [];
		$elements     = [];
		$priority     = 10;

		foreach ( $this->customer_push_event_categories() as $cat_id => $cat ) {
			$section_id = 'events_' . $cat_id;

			foreach ( $cat['events'] as $event ) {
				$event_id  = $event['id'];
				$saved     = is_array( $saved_events[ $event_id ] ?? null ) ? $saved_events[ $event_id ] : [];
				$vars_hint = sprintf(
					/* translators: %s: comma-separated variable list */
					__( 'Available variables: %s', 'app-bridge' ),
					$this->event_variables_hint( $event_id )
				);

				$elements[] = [
					'id'                  => $event_id,
					'type'                => 'field',
					'variant'             => 'notification_event',
					'section_id'          => $section_id,
					'value'               => [
						'enabled' => (bool) ( $saved['enabled'] ?? true ),
						'title'   => (string) ( $saved['title'] ?? $event['title'] ),
						'body'    => (string) ( $saved['body'] ?? $event['body'] ),
					],
					'event_label'         => $event['label'],
					'event_channel'       => $event['channel'],
					'event_default_title' => $event['title'],
					'event_default_body'  => $event['body'],
					'event_vars_hint'     => $vars_hint,
					'priority'            => $priority,
				];

				$priority += 10;
			}
		}

		return $elements;
	}

	/**
	 * Returns a comma-separated list of template variables available for the
	 * given event's message body. Kept minimal so the hint stays useful.
	 */
	private function event_variables_hint( string $event_id ): string {
		$map = [
			'order_'   => '{order_number}, {amount}',
			'payment_' => '{order_number}, {amount}',
			'refund_'  => '{order_number}, {amount}',
			'support_' => '{order_number}, {ticket_id}',
			'review_'  => '{product_name}',
			'account_' => '{site_name}',
		];
		foreach ( $map as $prefix => $vars ) {
			if ( strpos( $event_id, $prefix ) === 0 ) {
				return $vars;
			}
		}
		return '';
	}
}
