<?php

namespace WeDevs\AppBridge\Integrations\Dokan;

use WeDevs\AppBridge\Core\AbstractSettingsSchema;
use WeDevs\AppBridge\Core\Auth\JwtAuth;
use WeDevs\AppBridge\Integrations\Dokan\Notifications\VendorEventCatalog;

class SettingsSchema extends AbstractSettingsSchema {

	private LicenseManager $license_manager;

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

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

	/**
	 * Use a vendor-app specific option key so the Dokan integration doesn't
	 * inherit the `pocket_store_*` naming reserved for the customer app.
	 */
	public function get_option_key(): string {
		return 'app_bridge_vendor_settings';
	}

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

	protected function button_colors_section(): array {
		return [];
	}

	protected function button_color_fields( array $settings ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
		return [];
	}

	// Vendor App does not expose the App Languages picker.
	protected function languages_section(): array {
		return [];
	}

	protected function languages_fields( array $settings ): array { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter
		return [];
	}

	/**
	 * Extend app identity with the shared JWT auth secret key. The key is
	 * persisted to the dedicated `app_bridge_jwt_auth_secret_key` wp_option so
	 * the Pocket Store and Vendor App settings pages share a single source.
	 */
	// Vendor App does not expose `app_logo` — opt out of the inherited builder.
	protected function app_logo_field( array $settings ): array {
		return [];
	}

	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. Shared with Pocket Store.', 'app-bridge' ),
				],
			],
			parent::app_identity_fields( $settings )
		);
	}

	// 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',
		];
	}

	// ── Dokan-specific sections ───────────────────────────────────────────────

	protected function sections(): array {
		return array_merge(
			[
				[
					'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,
				],
			],
			$this->push_notification_event_sections(),
		);
	}

	// ── Dokan-specific fields ─────────────────────────────────────────────────

	protected function fields( array $settings ): array {
		return array_merge(
			$this->push_notification_event_fields( $settings ),
			[ $this->send_notification_form_field() ],
		);
	}

	/**
	 * Custom field rendered by the `send_notification_form` variant. The
	 * vendor-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 );

		if ( isset( $data['vendor_app'] ) ) {
			$s                         = $data['vendor_app'];
			$result['enable_vendor_app'] = (bool) ( $s['enable_vendor_app'] ?? true );
			$result['vendor_tagline']    = sanitize_text_field( $s['vendor_tagline'] ?? '' );
		}

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

		return $result;
	}

	/**
	 * Persists the shared JWT secret to its dedicated wp_option in addition
	 * to the standard per-integration save, so Pocket Store and Vendor App
	 * read/write a single source.
	 */
	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
			);
		}
	}

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

	/**
	 * Catalog of Vendor App push-notification events grouped by category.
	 *
	 * Sourced from {@see VendorEventCatalog} 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 vendor_push_event_categories(): array {
		return VendorEventCatalog::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->vendor_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.
	 * See {@see \WeDevs\AppBridge\Integrations\WooCommerce\SettingsSchema::push_notification_event_fields}.
	 *
	 * @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->vendor_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.
	 */
	private function event_variables_hint( string $event_id ): string {
		$map = [
			'order_'    => '{order_number}, {amount}, {status}',
			'withdraw_' => '{amount}, {method}',
			'product_'  => '{product_name}, {stock_count}',
			'store_'    => '{store_name}',
			'review_'   => '{product_name}, {rating}',
			'support_'  => '{order_number}, {ticket_id}',
			'account_'  => '{site_name}',
		];
		foreach ( $map as $prefix => $vars ) {
			if ( strpos( $event_id, $prefix ) === 0 ) {
				return $vars;
			}
		}
		return '';
	}
}
