<?php
namespace Prodigy\Includes\Content;

use Prodigy\admin\Prodigy_Admin_Setup_Wizard;
use Prodigy\includes\models\Prodigy_Options;

defined( 'ABSPATH' ) || exit;

/**
 * HS platform settings parser
 *
 * @version 3.1.8
 */
class Prodigy_Settings_Parser extends Prodigy_Main_Content {

	public const REQUIRE_LOGIN_OPTION           = 'prodigy_require_login_option';
	public const APP_INCLUDES                   = 'apps';
	public const STATISTIC_APP_INCLUDES         = 'statistic-apps';
	public const PRODUCT_SETTINGS_INCLUDES      = 'product-setting';
	public const PLATFORM_APP                   = 'prodigy_app_';
	public const PLATFORM_DOMAIN                = 'prodigy_platform_domain';
	public const APP_PERSONALISATION_FEATURE    = 'prodigy_app_personalization_feature';
	public const APP_GIFT_CARDS_APP             = 'prodigy_app_gift_cards';
	public const APP_SUBSCRIPTION_FEATURE       = 'prodigy_app_subscription_enabled';
	public const APP_REDEMPTION_STORE           = 'prodigy_app_redemption_store_status';
	public const APP_LOGO_MANAGEMENT            = 'prodigy_app_logo_management';
	public const APP_BRANDS                     = 'prodigy_app_prodigy_brands';
	public const APP_GOOGLE_ANALYTICS           = 'prodigy_app_google_analytics';
	public const PRODUCT_PAGE_PRICE_SETTINGS    = 'prodigy_app_price-display-mode';
	public const STORE_CUSTOMIZATION_SETTINGS   = 'store-customization-settings';
	public const CUSTOMIZATION_ERROR_MESSAGES   = 'error-messages';
	public const THANK_YOU_PAGE_TITLE           = 'prodigy_thank_you_page_title';
	public const THANK_YOU_PAGE_BODY            = 'prodigy_thank_you_page_body';
	public const THANK_YOU_PAGE_ENABLE_BACK_BTN = 'prodigy_thank_you_page_enable_back_btn';
	public const THANK_YOU_PAGE_BUTTON_TEXT     = 'prodigy_thank_you_page_button_text';
	public const ERROR_ACCESS_RIGHTS_NUMBER     = 'prodigy_error_access_rights_number';
	public const ERROR_ACCESS_RIGHTS_TITLE      = 'prodigy_error_access_rights_title';
	public const ERROR_ACCESS_RIGHTS_BODY       = 'prodigy_error_access_rights_body';
	public const ERROR_PAGE_NOT_FOUND_NUMBER    = 'prodigy_error_page_not_found_number';
	public const ERROR_PAGE_NOT_FOUND_TITLE     = 'prodigy_error_page_not_found_title';
	public const ERROR_PAGE_NOT_FOUND_BODY      = 'prodigy_error_page_not_found_body';



	/**
	 * @param array $response
	 *
	 * @return void
	 */
	public function set_platform_settings( array $response ): void {
		$included_index = $this->build_included_index( $response['included'] ?? array() );

		$included_options = array_merge(
			$this->parse_settings( $response, self::APP_INCLUDES, $included_index ),
			$this->parse_settings( $response, self::STATISTIC_APP_INCLUDES, $included_index )
		);

		$included_product_settings = $this->parse_product_settings( $response, self::PRODUCT_SETTINGS_INCLUDES );

		$customization_items = $included_index[ self::STORE_CUSTOMIZATION_SETTINGS ] ?? array();
		$store_customization = $customization_items ? current( $customization_items ) : array();
		$error_items         = array_values( $included_index[ self::CUSTOMIZATION_ERROR_MESSAGES ] ?? array() );

		Prodigy_Options::invalidate_app_options();
		$this->set_app_settings( $included_options );
		$this->set_product_settings( $included_product_settings['attributes'] ?? array() );
		$this->set_thank_you_page_settings( $store_customization['attributes'] ?? array() );
		$this->set_error_page_settings( $error_items );
		if ( isset( $response['data'] ) ) {
			$this->set_general_settings( $response['data']['attributes'] ?? array() );
			$this->set_login_settings( $response['data']['attributes']['accounts'] ?? '' );
			$this->set_redemption_store_status( $response['data']['attributes']['redemption-store'] ?? false );
		}
	}

	/**
	 * Build a lookup index from the included array keyed by [type][id].
	 *
	 * @param array $included
	 *
	 * @return array
	 */
	private function build_included_index( array $included ): array {
		$index = array();
		foreach ( $included as $item ) {
			if ( isset( $item['id'], $item['type'] ) ) {
				$index[ $item['type'] ][ (int) $item['id'] ] = $item;
			}
		}
		return $index;
	}


	/**
	 * @param  bool $status
	 *
	 * @return void
	 */
	public static function set_redemption_store_status( bool $status ): void {
		update_option( self::APP_REDEMPTION_STORE, $status );
	}

	/**
	 * @param array $response
	 *
	 * @return void
	 */
	public function set_general_settings( array $response ): void {
		update_option( self::APP_SUBSCRIPTION_FEATURE, $response['subscriptions-enabled'] ?? false );

		if ( isset( $response['connected'] ) && $response['connected'] ) {
			update_option( self::APP_BRANDS, $response['multi-brands'] ?? false );
			update_option( self::APP_PERSONALISATION_FEATURE, $response['personalizations-enabled'] ?? false );
		}
	}

	/**
	 * @param array $settings
	 *
	 * @return void
	 */
	public function set_product_settings( array $settings ): void {
		foreach ( $settings as $key => $value ) {
			if ( isset( $key, $value ) ) {
				update_option( self::PLATFORM_APP . $key, $value );
			}
		}
	}

	/**
	 * Set HS platform settings
	 *
	 * @param array $settings
	 *
	 * @return void
	 */
	public function set_app_settings( array $settings ): void {
		foreach ( $settings as $value ) {
			if ( isset( $value['attributes']['name'], $value['attributes']['connected'] ) && $value['type'] === self::APP_INCLUDES ) {
				update_option( self::PLATFORM_APP . $value['attributes']['name'], $value['attributes']['connected'] );
			}

			if ( isset( $value['attributes']['name'] ) && $value['type'] === self::STATISTIC_APP_INCLUDES ) {
				if ( isset( $value['attributes']['external-key'] ) ) {
					update_option( self::PLATFORM_APP . $value['attributes']['name'], ! empty( $value['attributes']['external-key'] ) );
					update_option( self::PLATFORM_APP . $value['attributes']['name'] . '_key', $value['attributes']['external-key'] );
				}
			}
		}
	}

	/**
	 * Set HS platform settings
	 *
	 * @param string $settings
	 *
	 * @return void
	 */
	public function set_login_settings( string $settings ): void {
		update_option( self::REQUIRE_LOGIN_OPTION, $settings );
	}

	/**
	 * @param array $attributes
	 *
	 * @return void
	 */
	public function set_thank_you_page_settings( array $attributes ): void {
		if ( isset( $attributes['thank-you-page-title'] ) ) {
			update_option( self::THANK_YOU_PAGE_TITLE, $attributes['thank-you-page-title'] );
		}
		if ( isset( $attributes['thank-you-page-body'] ) ) {
			update_option( self::THANK_YOU_PAGE_BODY, $attributes['thank-you-page-body'] );
		}
		if ( isset( $attributes['thank-you-page-enable-back-to-shop-button'] ) ) {
			update_option( self::THANK_YOU_PAGE_ENABLE_BACK_BTN, $attributes['thank-you-page-enable-back-to-shop-button'] ? '1' : '0' );
		}
		if ( isset( $attributes['thank-you-page-button-text'] ) ) {
			update_option( self::THANK_YOU_PAGE_BUTTON_TEXT, $attributes['thank-you-page-button-text'] );
		}
	}

	/**
	 * @param array $error_items
	 *
	 * @return void
	 */
	public function set_error_page_settings( array $error_items ): void {
		$option_map = array(
			'access_rights_error'  => array(
				'number' => self::ERROR_ACCESS_RIGHTS_NUMBER,
				'title'  => self::ERROR_ACCESS_RIGHTS_TITLE,
				'body'   => self::ERROR_ACCESS_RIGHTS_BODY,
			),
			'page_not_found_error' => array(
				'number' => self::ERROR_PAGE_NOT_FOUND_NUMBER,
				'title'  => self::ERROR_PAGE_NOT_FOUND_TITLE,
				'body'   => self::ERROR_PAGE_NOT_FOUND_BODY,
			),
		);

		foreach ( $error_items as $item ) {
			$attrs      = $item['attributes'] ?? array();
			$error_type = $this->normalize_error_type(
				$this->get_first_attribute_value( $attrs, array( 'identifier', 'error-type', 'error_type', 'type' ) ) ?? ''
			);
			if ( ! isset( $option_map[ $error_type ] ) ) {
				continue;
			}
			$options = $option_map[ $error_type ];

			$error_number = $this->get_first_attribute_value( $attrs, array( 'error-number', 'error_number', 'number' ) );
			if ( $error_number !== null ) {
				update_option( $options['number'], $error_number );
			}

			$error_title = $this->get_first_attribute_value(
				$attrs,
				array( 'error-title', 'error_title', 'title', 'message', 'error-message', 'error_message' )
			);
			if ( $error_title !== null ) {
				update_option( $options['title'], $error_title );
			}

			$error_body = $this->get_first_attribute_value(
				$attrs,
				array( 'error-body', 'error_body', 'body', 'description', 'error-description', 'error_description' )
			) ?? '';
			update_option( $options['body'], $error_body );
		}
	}

	/**
	 * @param array $attributes Attribute payload from the settings endpoint.
	 * @param array $keys       Candidate keys in priority order.
	 *
	 * @return string|null
	 */
	private function get_first_attribute_value( array $attributes, array $keys ): ?string {
		foreach ( $keys as $key ) {
			if ( isset( $attributes[ $key ] ) ) {
				return (string) $attributes[ $key ];
			}
		}

		return null;
	}

	/**
	 * @param string $error_type Error type received from the settings endpoint.
	 *
	 * @return string
	 */
	private function normalize_error_type( string $error_type ): string {
		$error_type = strtolower( trim( str_replace( '-', '_', $error_type ) ) );
		$aliases    = array(
			'access_rights'         => 'access_rights_error',
			'access_rights_error'   => 'access_rights_error',
			'403'                   => 'access_rights_error',
			'page_not_found'        => 'page_not_found_error',
			'page_not_found_error'  => 'page_not_found_error',
			'not_found'             => 'page_not_found_error',
			'not_found_error'       => 'page_not_found_error',
			'404'                   => 'page_not_found_error',
		);

		return $aliases[ $error_type ] ?? $error_type;
	}

	/**
	 * @param   array  $settings_response
	 * @param   string $type
	 * @param   array  $included_index    Pre-built index keyed by [type][id] (optional, built once by set_platform_settings).
	 *
	 * @return array
	 */
	public function parse_settings( array $settings_response, string $type, array $included_index = array() ): array {
		$result = array();
		if ( ! isset( $settings_response['data']['relationships'][ $type ]['data'] ) ) {
			return $result;
		}

		foreach ( $settings_response['data']['relationships'][ $type ]['data'] as $app ) {
			$id = (int) ( $app['id'] ?? 0 );
			if ( ! $id ) {
				continue;
			}
			$item = $included_index[ $type ][ $id ] ?? array();
			if ( ! empty( $item ) ) {
				$result[] = $item;
			}
		}

		return $result;
	}

	/**
	 * @param array  $settings_response
	 * @param string $type
	 *
	 * @return array
	 */
	public function parse_product_settings( array $settings_response, string $type ): array {
		$result = array();
		if ( isset( $settings_response['data']['relationships'][ $type ]['data'] ) ) {
			if ( $type === self::PRODUCT_SETTINGS_INCLUDES ) {
				$settings_response['data']['relationships']['product-settings']['data'] = $settings_response['data']['relationships'][ $type ]['data'];
				unset( $settings_response['data']['relationships'][ $type ] );
				$type = 'product-settings';

				foreach ( $settings_response['data']['relationships'] as $key => $item ) {
					if ( $key === $type ) {
						$service_id = $settings_response['data']['relationships'][ $type ]['data']['id'];
						$result     = $this->parse_included_obj_by_id( $settings_response, $service_id, $type );
					}
				}
			}
		}

		return $result;
	}
}
