<?php

namespace ElementPack\Modules\SoundEffects\Normalizers;

use ElementPack\Modules\SoundEffects\Atomic\Support;

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

class Settings_Normalizer {
	public function normalize( $widget ) {
		$atomic_settings = $this->normalize_atomic_settings( $widget );

		if ( $atomic_settings ) {
			return $atomic_settings;
		}

		return $this->normalize_legacy_settings( $widget );
	}

	private function normalize_atomic_settings( $widget ) {
		$candidates = [];

		if ( method_exists( $widget, 'get_atomic_setting' ) ) {
			$candidates[] = [
				Support::ACTIVE_KEY => $widget->get_atomic_setting( Support::ACTIVE_KEY ),
				Support::SELECT_TYPE_KEY => $widget->get_atomic_setting( Support::SELECT_TYPE_KEY ),
				Support::ELEMENT_SELECTOR_KEY => $widget->get_atomic_setting( Support::ELEMENT_SELECTOR_KEY ),
				Support::EVENT_KEY => $widget->get_atomic_setting( Support::EVENT_KEY ),
				Support::SOURCE_KEY => $widget->get_atomic_setting( Support::SOURCE_KEY ),
				Support::SOURCE_LOCAL_LINK_KEY => $widget->get_atomic_setting( Support::SOURCE_LOCAL_LINK_KEY ),
				Support::HOSTED_URL_KEY => $widget->get_atomic_setting( Support::HOSTED_URL_KEY ),
				Support::HOSTED_URL_MP3_KEY => $widget->get_atomic_setting( Support::HOSTED_URL_MP3_KEY ),
			];
		}

		if ( method_exists( $widget, 'get_data' ) ) {
			$raw_settings = $widget->get_data( 'settings' );

			if ( is_array( $raw_settings ) ) {
				$candidates[] = $raw_settings;
			}
		}

		foreach ( $candidates as $candidate ) {
			$normalized = $this->normalize_settings_array( $candidate, true );

			if ( $normalized ) {
				return $normalized;
			}
		}

		return null;
	}

	private function normalize_legacy_settings( $widget ) {
		if ( ! method_exists( $widget, 'get_settings_for_display' ) ) {
			return null;
		}

		$settings = [
			Support::ACTIVE_KEY => $widget->get_settings_for_display( Support::ACTIVE_KEY ),
			Support::SELECT_TYPE_KEY => $widget->get_settings_for_display( Support::SELECT_TYPE_KEY ),
			Support::ELEMENT_SELECTOR_KEY => $widget->get_settings_for_display( Support::ELEMENT_SELECTOR_KEY ),
			Support::EVENT_KEY => $widget->get_settings_for_display( Support::EVENT_KEY ),
			Support::SOURCE_KEY => $widget->get_settings_for_display( Support::SOURCE_KEY ),
			Support::SOURCE_LOCAL_LINK_KEY => $widget->get_settings_for_display( Support::SOURCE_LOCAL_LINK_KEY ),
			Support::HOSTED_URL_KEY => $widget->get_settings_for_display( Support::HOSTED_URL_KEY ),
			Support::HOSTED_URL_MP3_KEY => $widget->get_settings_for_display( Support::HOSTED_URL_MP3_KEY ),
		];

		return $this->normalize_settings_array( $settings, false );
	}

	private function normalize_settings_array( array $settings, bool $unwrap_transformable ) {
		$active = $this->extract_value( $settings[ Support::ACTIVE_KEY ] ?? null, $unwrap_transformable );

		if ( ! $this->is_truthy( $active ) ) {
			return null;
		}

		return [
			'active' => 'yes',
			'select_type' => $this->extract_value( $settings[ Support::SELECT_TYPE_KEY ] ?? 'widget', $unwrap_transformable ) ?: 'widget',
			'element_selector' => $this->extract_value( $settings[ Support::ELEMENT_SELECTOR_KEY ] ?? '', $unwrap_transformable ) ?: '',
			'event' => $this->extract_value( $settings[ Support::EVENT_KEY ] ?? 'click', $unwrap_transformable ) ?: 'click',
			'source' => $this->extract_value( $settings[ Support::SOURCE_KEY ] ?? 'bubble', $unwrap_transformable ) ?: 'bubble',
			'source_local_link' => $this->extract_value( $settings[ Support::SOURCE_LOCAL_LINK_KEY ] ?? BDTEP_ASSETS_URL . 'sounds/', $unwrap_transformable ) ?: BDTEP_ASSETS_URL . 'sounds/',
			'hosted_url' => [
				'url' => $this->extract_media_url( $settings[ Support::HOSTED_URL_KEY ] ?? null, $unwrap_transformable ),
			],
			'hosted_url_mp3' => [
				'url' => $this->extract_media_url( $settings[ Support::HOSTED_URL_MP3_KEY ] ?? null, $unwrap_transformable ),
			],
		];
	}

	private function extract_media_url( $value, bool $unwrap_transformable ): string {
		$value = $this->extract_value( $value, $unwrap_transformable );

		if ( is_array( $value ) ) {
			return (string) ( $value['url'] ?? '' );
		}

		return is_string( $value ) ? $value : '';
	}

	private function extract_value( $value, bool $unwrap_transformable ) {
		if ( $unwrap_transformable && is_array( $value ) && isset( $value['value'] ) ) {
			return $this->extract_value( $value['value'], $unwrap_transformable );
		}

		return $value;
	}

	private function is_truthy( $value ): bool {
		return true === $value || 'yes' === $value || 1 === $value || '1' === $value;
	}
}
