<?php

// exit if accessed directly
if (! defined('ABSPATH')) {
	exit;
}

if (! class_exists('acf_field_font_awesome')) :

	class acf_field_font_awesome extends \acf_field {
		private $icons = false;
		private $version;
		public	$show_in_rest = true;
		private $env;

		public function __construct() {
			$this->version = 'v' . ACFFA_MAJOR_VERSION;
			$this->name = 'font-awesome';
			$this->label = __('Font Awesome Icon', 'acf-font-awesome');
			$this->category = 'content';

			$this->defaults = [
				'enqueue_fa' 		=>	0,
				'allow_null' 		=>	0,
				'show_preview'		=>	1,
				'save_format'		=>  'element',
				'default_value'		=>	'',
				'default_label'		=>	'',
				'fa_live_preview'	=>	'',
				'choices'			=>	[]
			];

			parent::__construct();

			if (apply_filters('ACFFA_always_enqueue_fa', false)) {
				add_action('wp_enqueue_scripts', [$this, 'frontend_enqueue_scripts']);
			} else {
				add_filter('acf/load_field', [$this, 'maybe_enqueue_font_awesome']);
			}

			add_filter('ACFFA_v5_upgrade_compat_selected_field_sets', [$this, 'v5_upgrade_compat_selected_field_sets'], 5, 1);
			add_filter('ACFFA_v5_upgrade_compat_format_value', [$this, 'v5_upgrade_compat_format_value'], 5, 2);
		}

		public function render_field_settings($field) {
			if (apply_filters('ACFFA_show_fontawesome_pro_blurbs', true)) {
				acf_render_field_setting($field, [
					'label'			=> __('Get FontAwesome Pro', 'acf-font-awesome'),
					'message'		=> '<p>' . __('Support this plugin and get more icons across more styles plus helpful services, regular updates, a lifetime license, and actual human support.', 'acf-font-awesome') . '</p>' . '<a class="get-acfpro-btn" target="_blank" href="https://fontawesome.com/referral?a=f4be3e1256"><i class="fa-solid fa-carrot"></i>' . __('Upgrade to Font Awesome Pro!', 'acf-font-awesome') . '</a>',
					'type'			=> 'message',
					'name'			=> 'get-fontawesome-pro',
					'class'			=> 'get-fontawesome-pro'
				]);
			}

			$icon_sets_args = [
				'label'			=> __('Icon Sets', 'acf-font-awesome'),
				'instructions'	=> __('Specify which icon set(s) to load', 'acf-font-awesome'),
				'type'			=> 'select',
				'name'			=> 'icon_sets',
				'multiple'     => 1,
				'ui'           => 1,
			];

			$icon_sets_args['choices'] = [
				'classic_solid'          => __('Classic (Solid)', 'acf-font-awesome'),
				'classic_regular'        => __('Classic (Regular)', 'acf-font-awesome'),
				'classic_light'          => __('Classic (Light)', 'acf-font-awesome'),
				'classic_thin'           => __('Classic (Thin)', 'acf-font-awesome'),
				'sharp_solid'            => __('Sharp (Solid)', 'acf-font-awesome'),
				'sharp_regular'          => __('Sharp (Regular)', 'acf-font-awesome'),
				'sharp_light'            => __('Sharp (Light)', 'acf-font-awesome'),
				'sharp_thin'             => __('Sharp (Thin)', 'acf-font-awesome'),
				'duotone_solid'          => __('Duotone (Solid)', 'acf-font-awesome'),
				'duotone_regular'        => __('Duotone (Regular)', 'acf-font-awesome'),
				'duotone_light'          => __('Duotone (Light)', 'acf-font-awesome'),
				'duotone_thin'           => __('Duotone (Thin)', 'acf-font-awesome'),
				'sharp-duotone_solid'    => __('Sharp Duotone (Solid)', 'acf-font-awesome'),
				'sharp-duotone_regular'  => __('Sharp Duotone (Regular)', 'acf-font-awesome'),
				'sharp-duotone_light'    => __('Sharp Duotone (Light)', 'acf-font-awesome'),
				'sharp-duotone_thin'     => __('Sharp Duotone (Thin)', 'acf-font-awesome'),
				'whiteboard_semibold'    => __('Whiteboard (Semibold)', 'acf-font-awesome'),
				'etch_solid'             => __('Etch (Solid)', 'acf-font-awesome'),
				'slab_regular'           => __('Slab (Regular)', 'acf-font-awesome'),
				'slab-press_regular'     => __('Slab Press (Regular)', 'acf-font-awesome'),
				'thumbprint_light'       => __('Thumbprint (Light)', 'acf-font-awesome'),
				'jelly_regular'          => __('Jelly (Regular)', 'acf-font-awesome'),
				'jelly-duo_regular'      => __('Jelly Duo (Regular)', 'acf-font-awesome'),
				'jelly-fill_regular'     => __('Jelly Fill (Regular)', 'acf-font-awesome'),
				'chisel_regular'         => __('Chisel (Regular)', 'acf-font-awesome'),
				'notdog_solid'           => __('Notdog (Solid)', 'acf-font-awesome'),
				'notdog-duo_solid'       => __('Notdog Duo (Solid)', 'acf-font-awesome'),
				'utility_semisolid'      => __('Utility (Solid)', 'acf-font-awesome'),
				'utility-duo_semisolid'  => __('Utility Duo (Solid)', 'acf-font-awesome'),
				'utility-fill_semisolid' => __('Utility Fill (Solid)', 'acf-font-awesome'),
				'graphite_thin'          => __('Graphite (Thin)', 'acf-font-awesome'),
				'fak'                    => __('Uploaded Icons', 'acf-font-awesome'),
				'brands'                 => __('Brands', 'acf-font-awesome')
			];

			// Fix duotone family previously saved with no style
			if (isset($field['icon_sets']) && is_array($field['icon_sets'])) {
				if (($key = array_search('duotone', $field['icon_sets'])) !== FALSE) {
					$field['icon_sets'][$key] = 'duotone_solid';
				}
			}

			$selected_field_sets	= ! empty($field['icon_sets']) ? $field['icon_sets'] : ['classic_solid', 'classic_regular', 'brands'];
			$selected_field_sets	= apply_filters('ACFFA_v5_upgrade_compat_selected_field_sets', $selected_field_sets);

			$icon_sets_args['value'] = $selected_field_sets;

			acf_render_field_setting($field, $icon_sets_args);

			acf_render_field_setting($field, [
				'label'			=> __('Default Label', 'acf-font-awesome'),
				'instructions'	=> 'Used internally to store the select label for the default icon. For performance reasons.',
				'type'			=> 'text',
				'name'			=> 'default_label',
				'value'			=> ! empty($field['default_label']) ? $field['default_label'] : $field['default_value'],
				'class'			=> 'default_value'
			]);

			acf_render_field_setting($field, [
				'label'			=> __('Default Icon', 'acf-font-awesome'),
				'instructions'	=> '',
				'type'			=> 'text',
				'name'			=> 'default_value',
				'class'	  		=> 'acffa-default-icon',
				'value'			=> $field['default_value'] ?? '',
				'placeholder'	=> 'Choose a default icon (optional)',
				'allow_null'	=> 1,
			]);

			acf_render_field_setting($field, [
				'label'			=> __('Return Value', 'acf-font-awesome'),
				'instructions'	=> __('Specify the returned value on front end', 'acf-font-awesome'),
				'type'			=> 'radio',
				'name'			=> 'save_format',
				'choices'	=>	[
					'element'	=>	__('Icon Element', 'acf-font-awesome'),
					'class'		=>	__('Icon Class', 'acf-font-awesome'),
					'unicode'	=>	__('Icon Unicode', 'acf-font-awesome'),
					'object'	=>	__('Icon Object', 'acf-font-awesome'),
				]
			]);

			acf_render_field_setting($field, [
				'label'			=> __('Allow Null?', 'acf-font-awesome'),
				'instructions'	=> '',
				'type'			=> 'radio',
				'name'			=> 'allow_null',
				'choices'	=>	[
					1	=>	__('Yes', 'acf-font-awesome'),
					0	=>	__('No', 'acf-font-awesome')
				]
			]);

			acf_render_field_setting($field, [
				'label'			=> __('Show Icon Preview', 'acf-font-awesome'),
				'instructions'	=> __('Set to \'Yes\' to include a larger icon preview on any admin pages using this field.', 'acf-font-awesome'),
				'type'			=> 'radio',
				'name'			=> 'show_preview',
				'choices'	=>	[
					1	=>	__('Yes', 'acf-font-awesome'),
					0	=>	__('No', 'acf-font-awesome')
				]
			]);

			if (! apply_filters('ACFFA_always_enqueue_fa', false)) {
				acf_render_field_setting($field, [
					'label'			=> __('Enqueue FontAwesome?', 'acf-font-awesome'),
					'instructions'	=> __('Set to \'Yes\' to enqueue FA in the footer on any pages using this field.', 'acf-font-awesome'),
					'type'			=> 'radio',
					'name'			=> 'enqueue_fa',
					'choices'	=>	[
						1	=>	__('Yes', 'acf-font-awesome'),
						0	=>	__('No', 'acf-font-awesome')
					]
				]);
			}
		}

		public function render_field($field) {
			if ($field['allow_null']) {
				$select_value = $field['value'];
			} else {
				$select_value = ('null' != $field['value']) ? $field['value'] : $field['default_value'];
			}

			$v5_icon_preselected = false;

			$field['type']		= 'text';
			$field['value']		= $select_value;
			$field['icon_sets']	= isset($field['icon_sets']) ? apply_filters('ACFFA_standardize_icon_set_family_style', $field['icon_sets']) : ['classic_solid', 'classic_regular', 'brands'];
			$field['prepend'] = '';
			$field['append'] = '';
			$field['class']		= $v5_icon_preselected ? 'v5_icon_preselected selected-icon hidden' : 'selected-icon hidden';

			if ($select_value) :
				$icon_info = json_decode($select_value);
				if (is_object($icon_info)) {
					$family = isset($icon_info->family) ? $icon_info->family : apply_filters('ACFFA_default_family_by_style', 'classic', $icon_info->style);
					$style = isset($icon_info->style) ? $icon_info->style : '';
					$classes = [];
					if ('classic' !== $family) {
						$classes[] = 'fa-' . str_replace('_', '-', $family);
					}
					if ($style) {
						$classes[] = 'fa-' . $style;
					}
					$classes[] = 'fa-' . $icon_info->id;
				} else {
					$v5_icon_preselected	= true;
					$options				= get_option('acffa_settings');
					$label					= isset($options['acffa_v5_compatibility_mode']) && $options['acffa_v5_compatibility_mode'] ? '[v5-compat-lookup]' : false;
				}
			endif;

			if ($field['show_preview']) :
				if ($v5_icon_preselected) :
?>
					<div class="icon_preview v5-compat-alert show-alert">
						<i class="fas fa-exclamation-circle"></i>
					</div>
				<?php
				else :
				?>
					<?php if (isset($icon_info) && is_object($icon_info)) : ?>
						<div class="icon_preview">
							<i class="<?php echo esc_attr(implode(' ', $classes)); ?>"></i>
						</div>
					<?php else : ?>
						<div class="icon_preview">
						</div>
					<?php endif; ?>
				<?php endif; ?>
				<button type="button" class="button fa-icon-chooser-open"><?php esc_html_e('Choose icon', 'acf-font-awesome'); ?></button>
				<?php if ($field['allow_null']) : ?>
					<button type="button" class="fa-icon-clear" title="<?php esc_html_e('Clear icon', 'acf-font-awesome'); ?>">
						<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640"><!--!Font Awesome Free v7.2.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2026 Fonticons, Inc.-->
							<path d="M183.1 137.4C170.6 124.9 150.3 124.9 137.8 137.4C125.3 149.9 125.3 170.2 137.8 182.7L275.2 320L137.9 457.4C125.4 469.9 125.4 490.2 137.9 502.7C150.4 515.2 170.7 515.2 183.2 502.7L320.5 365.3L457.9 502.6C470.4 515.1 490.7 515.1 503.2 502.6C515.7 490.1 515.7 469.8 503.2 457.3L365.8 320L503.1 182.6C515.6 170.1 515.6 149.8 503.1 137.3C490.6 124.8 470.3 124.8 457.8 137.3L320.5 274.7L183.1 137.4z" />
						</svg>
					</button>
				<?php endif; ?>
				<input type="hidden" name="acffa_nonce" class="acffa-nonce" value="<?= esc_attr(wp_create_nonce('acffa_nonce')); ?>" />
				<input type="hidden" name="icon_sets" class="icon-sets" value="<?= esc_attr(implode(',', $field['icon_sets'] ?: [])); ?>" />
			<?php
			endif;

			if ($v5_icon_preselected) :
				$previous_icon_info = $this->get_previous_icon_info($select_value);
			?>
				<div class="v5-compat-message" aria-label="<?php esc_html_e('This FontAwesome v5 Pro icon cannot be automatically translated to its v6 equivalent and will need to be reselected before saving this post/page.', 'acf-font-awesome'); ?>" data-microtip-size="large" data-microtip-position="top" role="tooltip">
					<?php echo sprintf(esc_html__('Please reselect your FontAwesome Icon.', 'acf-font-awesome'), 'SOLID', 'COFFEE'); ?> <i class="fas fa-question-circle"></i>
					<?php
					if (isset($previous_icon_info['style']) && ! empty($previous_icon_info['style'])) :
					?>
						<em><?php esc_html_e('Style:', 'acf-font-awesome'); ?></em> <strong><?php echo esc_html($previous_icon_info['style']); ?></strong>
					<?php
					endif;
					if (isset($previous_icon_info['name']) && ! empty($previous_icon_info['name'])) :
					?>
						<em><?php esc_html_e('Name:', 'acf-font-awesome'); ?></em> <strong><?php echo esc_html($previous_icon_info['name']); ?></strong>
					<?php
					endif;
					?>
				</div>
<?php
			endif;

			acf_render_field($field);
		}

		public function input_admin_enqueue_scripts() {
			$version		= ACFFA_VERSION;
			$options		= get_option('acffa_settings');
			$latest_version	= apply_filters('ACFFA_get_latest_version', '6.0.0');

			if (isset($options['acffa_v5_compatibility_mode']) && $options['acffa_v5_compatibility_mode']) {
				wp_enqueue_script('acffa_fontawesome-js-api', "https://use.fontawesome.com/releases/v$latest_version/js/all.js", [], $latest_version);
			}
			wp_register_script_module('acffa-icon-chooser-module', ACFFA_PUBLIC_PATH . "assets/js/fa-icon-chooser.esm.js", [], $version);
			wp_enqueue_script_module('acffa-icon-chooser-module');
			wp_enqueue_script('acf-input-font-awesome', ACFFA_PUBLIC_PATH . "assets/js/input-v7.js", ['acf-input'], $version);
			wp_localize_script('acf-input-font-awesome', 'ACFFA', [
				'major_version'		=> ACFFA_MAJOR_VERSION,
				'v5_compat_mode'	=> isset($options['acffa_v5_compatibility_mode']) && $options['acffa_v5_compatibility_mode'] ? true : false,
				'kit_token'			=> apply_filters('ACFFA_fontawesome_kit_token', false),
				'latest_version'	=> $latest_version,
				'nonce'				=> wp_create_nonce('acffa_nonce'),
				'ajax_url'			=> admin_url('admin-ajax.php')
			]);

			wp_enqueue_style('acf-input-microtip', ACFFA_PUBLIC_PATH . "assets/inc/microtip/microtip.min.css", [], '1.0.0');
			wp_enqueue_style('acf-input-font-awesome', ACFFA_PUBLIC_PATH . "assets/css/input.css", ['acf-input'], $version);

			if (apply_filters('ACFFA_admin_enqueue_fa', true)) {
				$fa_url = apply_filters('ACFFA_get_fa_url', '');
				if (stristr($fa_url, 'https://kit.fontawesome.com/')) {
					wp_enqueue_script('acffa_font-awesome-kit', $fa_url);
				} else {
					wp_enqueue_style('acffa_font-awesome', $fa_url, ['acf-input'], $latest_version);
				}
			}
		}

		public function maybe_enqueue_font_awesome($field) {
			if ('font-awesome' == $field['type'] && $field['enqueue_fa']) {
				add_action('wp_footer', [$this, 'frontend_enqueue_scripts']);
			}

			return $field;
		}

		public function frontend_enqueue_scripts() {
			$fa_url = apply_filters('ACFFA_get_fa_url', '');
			if (stristr($fa_url, 'https://kit.fontawesome.com/')) {
				wp_enqueue_script('acffa_font-awesome-kit', $fa_url);
			} else {
				$latest_version	= apply_filters('ACFFA_get_latest_version', '6.0.0');
				wp_enqueue_style('acffa_font-awesome', $fa_url, [], $latest_version);
			}
		}

		public function format_value($value, $post_id, $field) {
			if ('null' == $value) {
				return false;
			}

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

			$icon_json = json_decode($value);

			if (is_object($icon_json)) {
				$family = isset($icon_json->family) ? $icon_json->family : apply_filters('ACFFA_default_family_by_style', 'classic', $icon_json->style);
				$style = isset($icon_json->style) ? $icon_json->style : '';
				$classes = [];
				if ('classic' !== $family) {
					$classes[] = 'fa-' . str_replace('_', '-', $family);
				}
				if ($style) {
					$classes[] = 'fa-' . $style;
				}
				$classes[] = 'fa-' . $icon_json->id;
				$class = implode(' ', $classes);
				$prefix = implode(' ', array_slice($classes, 0, -1));

				switch ($field['save_format']) {
					case 'element':
						$value = '<i class="' . esc_attr($class) . '" aria-hidden="true"></i>';
						break;

					case 'unicode':
						$value = '&#x' . esc_attr($icon_json->unicode) . ';';
						break;

					case 'class':
						$value = esc_attr($class);
						break;

					case 'object':
						$object_data = [
							'element'	=> '<i class="' . esc_attr($class) . '" aria-hidden="true"></i>',
							'class'		=> $class,
							'id'		=> $icon_json->id,
							'family'	=> $family,
							'style' 	=> $icon_json->style,
							'prefix' 	=> $prefix,
							'hex' 		=> '\\' . $icon_json->unicode,
							'unicode' 	=> '&#x' . $icon_json->unicode . ';'
						];

						if ('fak' == $icon_json->style || 'custom' == $icon_json->style) {
							$path_data_element = '<svg class="svg-inline--fa" viewBox="0 0 ' . $icon_json->width . ' ' . $icon_json->height . '">';
							if (is_array($icon_json->path)) {
								foreach ($icon_json->path as $path) {
									if (! empty($path)) {
										$path_data_element .= '<path d="' . $path . '" />';
									}
								}
							} else {
								$path_data_element .= '<path d="' . $icon_json->path . '" />';
							}
							$path_data_element .= '</svg>';

							$svg_data = [
								'element'	=> isset($icon_json->html) ? $icon_json->html : $path_data_element,
								'path'		=> $icon_json->path,
								'height'	=> $icon_json->height,
								'width'		=> $icon_json->width
							];
							$object_data['svg'] = (object) $svg_data;
						}

						$value = (object) $object_data;
						break;
				}
			} else {
				$value = apply_filters('ACFFA_v5_upgrade_compat_format_value', $value, $field['save_format']);
			}

			return $value;
		}

		public function v5_upgrade_compat_format_value($value, $save_format) {
			if ('false' == $value) {
				return;
			}

			$icons		= get_option('ACFFA_icon_data');
			$version	= get_option('ACFFA_current_version', '5.15.4');

			if (! $icons || ! isset($icons[$version])) {
				return $value;
			}

			$icons = $icons[$version];

			if (version_compare($version, 5, '<')) {
				$icon = isset($icons['details'][$value]) ? $icons['details'][$value] : false;
			} else {
				$prefix = substr($value, 0, 3);
				$icon = isset($icons['details'][$prefix][$value]) ? $icons['details'][$prefix][$value] : false;
			}

			if ($icon) {
				switch ($save_format) {
					case 'element':
						if (version_compare($version, 5, '<')) {
							$value = '<i class="fa ' . $value . '" aria-hidden="true"></i>';
						} else {
							$value = '<i class="' . $value . '" aria-hidden="true"></i>';
						}
						break;

					case 'unicode':
						$value = $icon['unicode'];
						break;

					case 'object':
						$object_data = array(
							'element' => '<i class="' . $value . '" aria-hidden="true"></i>',
							'class' => $value,
							'hex' => $icon['hex'],
							'unicode' => $icon['unicode']
						);

						if (version_compare($version, 5, '>=')) {
							$object_data['prefix'] = $prefix;
						}

						$value = (object) $object_data;
						break;
				}
			}

			return $value;
		}

		public function v5_upgrade_compat_selected_field_sets($selected_field_sets) {
			if (is_array($selected_field_sets) && ! empty($selected_field_sets)) {
				foreach ($selected_field_sets as $key => $field_set) {
					switch ($field_set) {
						case 'fas':
							unset($selected_field_sets[$key]);
							$selected_field_sets[] = 'solid';
							break;

						case 'far':
							unset($selected_field_sets[$key]);
							$selected_field_sets[] = 'regular';
							break;

						case 'fal':
							unset($selected_field_sets[$key]);
							$selected_field_sets[] = 'light';
							break;

						case 'fad':
							unset($selected_field_sets[$key]);
							$selected_field_sets[] = 'duotone';
							break;

						case 'fab':
							unset($selected_field_sets[$key]);
							$selected_field_sets[] = 'brands';
							break;
					}
				}
			}

			return $selected_field_sets;
		}

		private function get_previous_icon_info($previous_icon) {
			if (! $previous_icon || 'false' == $previous_icon) {
				return;
			}

			if (0 === strpos($previous_icon, 'fa-')) {
				$icon_info	= [
					'name'	=> preg_replace('/-o$/', '', substr($previous_icon, 3))
				];
			} else {
				$icon_info	= [
					'style'	=> '',
					'name'	=> substr($previous_icon, 7)
				];

				$prefix = substr($previous_icon, 0, 3);

				switch ($prefix) {
					case 'fas':
						$icon_info['style'] = 'solid';
						break;

					case 'far':
						$icon_info['style'] = 'regular';
						break;

					case 'fal':
						$icon_info['style'] = 'light';
						break;

					case 'fad':
						$icon_info['style'] = 'duotone';
						break;

					case 'fab':
						$icon_info['style'] = 'brands';
						break;
				}
			}

			return $icon_info;
		}
	}

	acf_register_field_type('acf_field_font_awesome');

endif;
