<?php
/**
 * Element Pack Custom Fonts Admin
 * Handles admin UI, meta boxes, and file uploads
 *
 * @package ElementPack\Includes\CustomFonts
 */

namespace ElementPack\Includes\CustomFonts;

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

class EP_Custom_Fonts_Admin {

	private static $_instance = null;

	public static function instance() {
		if (is_null(self::$_instance)) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}

	private function __construct() {
		add_action('admin_menu', [$this, 'add_admin_menu'], 203);  // After Theme Builder (202)
		add_filter('parent_file', [$this, 'set_parent_file']);
		add_filter('submenu_file', [$this, 'set_submenu_file']);
		add_filter('enter_title_here', [$this, 'filter_title_placeholder'], 10, 2);
		add_action('add_meta_boxes', [$this, 'add_meta_boxes']);
		add_action('save_post_' . EP_Custom_Fonts_Manager::CPT, [$this, 'save_meta_box']);
		add_action('admin_enqueue_scripts', [$this, 'enqueue_admin_assets']);
		add_action('admin_head', [$this, 'print_list_screen_styles']);
		add_filter('manage_' . EP_Custom_Fonts_Manager::CPT . '_posts_columns', [$this, 'customize_columns']);
		add_action('manage_' . EP_Custom_Fonts_Manager::CPT . '_posts_custom_column', [$this, 'render_column'], 10, 2);
		add_filter('post_row_actions', [$this, 'customize_row_actions'], 10, 2);
		
		// Clear cache on save/delete
		add_action('save_post_' . EP_Custom_Fonts_Manager::CPT, [$this, 'clear_cache']);
		add_action('before_delete_post', [$this, 'clear_cache_on_delete'], 10, 2);
	}

	/**
	 * Match Elementor-style "Enter Font Family" title field.
	 *
	 * @param string  $placeholder Default placeholder.
	 * @param \WP_Post $post        Post object.
	 * @return string
	 */
	public function filter_title_placeholder($placeholder, $post) {
		if ($post && $post->post_type === EP_Custom_Fonts_Manager::CPT) {
			return esc_html__('Enter Font Family', 'bdthemes-element-pack');
		}
		return $placeholder;
	}

	/**
	 * Add admin menu (positioned after Theme Builder)
	 */
	public function add_admin_menu() {
		add_submenu_page(
			'element_pack_options',
			esc_html__('Custom Fonts', 'bdthemes-element-pack'),
			esc_html__('Custom Fonts', 'bdthemes-element-pack'),
			'manage_options',
			'edit.php?post_type=' . EP_Custom_Fonts_Manager::CPT,
			'',
			71  // Position right after Theme Builder (70)
		);
	}

	/**
	 * Set parent file to nest under Element Pack
	 */
	public function set_parent_file($parent_file) {
		global $current_screen;
		
		if ($current_screen && $current_screen->post_type === EP_Custom_Fonts_Manager::CPT) {
			return 'element_pack_options';
		}
		
		return $parent_file;
	}

	/**
	 * Set submenu file to highlight the menu item
	 */
	public function set_submenu_file($submenu_file) {
		global $current_screen;
		
		if ($current_screen && $current_screen->post_type === EP_Custom_Fonts_Manager::CPT) {
			return 'edit.php?post_type=' . EP_Custom_Fonts_Manager::CPT;
		}
		
		return $submenu_file;
	}

	/**
	 * Add meta boxes
	 */
	public function add_meta_boxes() {
		add_meta_box(
			'ep_font_files',
			esc_html__('Manage Your Font Files', 'bdthemes-element-pack'),
			[$this, 'render_meta_box'],
			EP_Custom_Fonts_Manager::CPT,
			'normal',
			'high'
		);
	}

	/**
	 * Font weight options shared by metabox and JS template.
	 *
	 * @return array<string, string>
	 */
	private function get_font_weight_choices() {
		return [
			'normal' => __('Normal', 'bdthemes-element-pack'),
			'bold'   => __('Bold', 'bdthemes-element-pack'),
			'100'    => '100',
			'200'    => '200',
			'300'    => '300',
			'400'    => '400',
			'500'    => '500',
			'600'    => '600',
			'700'    => '700',
			'800'    => '800',
			'900'    => '900',
		];
	}

	/**
	 * Allowed stored font_weight values.
	 *
	 * @return string[]
	 */
	private function get_allowed_font_weights() {
		return ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];
	}

	/**
	 * Sanitize font-weight for storage.
	 *
	 * @param string $weight Raw value.
	 * @return string
	 */
	private function sanitize_font_weight($weight) {
		$weight = sanitize_text_field($weight);
		return in_array($weight, $this->get_allowed_font_weights(), true) ? $weight : '400';
	}

	/**
	 * CSS font-weight value for inline preview (admin).
	 *
	 * @param string $weight Stored weight.
	 * @return string
	 */
	private function preview_font_weight_css($weight) {
		$weight = trim((string) $weight);
		if (in_array($weight, ['normal', 'bold'], true)) {
			return $weight;
		}
		if (preg_match('/^[1-9]00$/', $weight)) {
			return $weight;
		}
		return '400';
	}

	/**
	 * Render meta box (Elementor-style cards: weight, style, preview, file rows).
	 *
	 * @param \WP_Post $post Post.
	 */
	public function render_meta_box($post) {
		wp_nonce_field('ep_save_font_meta', 'ep_font_meta_nonce');

		$font_files = get_post_meta($post->ID, EP_Custom_Fonts_Manager::FONT_META_KEY, true);
		if (!is_array($font_files)) {
			$font_files = [];
		}

		// Add at least one empty row
		if (empty($font_files)) {
			$font_files = [
				[
					'font_weight' => '400',
					'font_style'  => 'normal',
					'woff'        => '',
					'woff2'       => '',
					'ttf'         => '',
					'otf'         => '',
					'svg'         => '',
					'eot'         => '',
				],
			];
		}

		$font_family = get_the_title($post->ID);
		if ($font_family !== '' && $post->ID) {
			$face_css = EP_Custom_Fonts_Manager::instance()->get_font_face_css($font_family);
			if ($face_css) {
				echo '<style id="ep-custom-font-admin-face">' . $face_css . '</style>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
			}
		}

		$weights = $this->get_font_weight_choices();
		$preview_raw = __('Think Big, Act Smarter', 'bdthemes-element-pack');

		?>
		<div class="ep-custom-fonts-wrapper ep-font-metabox-content">
			<div class="ep-font-variations">
				<?php foreach ($font_files as $index => $font_file) : ?>
					<?php
					$w = isset($font_file['font_weight']) ? $font_file['font_weight'] : '400';
					$s = isset($font_file['font_style']) ? $font_file['font_style'] : 'normal';
					$style_labels = [
						'normal'  => __('Normal', 'bdthemes-element-pack'),
						'italic'  => __('Italic', 'bdthemes-element-pack'),
						'oblique' => __('Oblique', 'bdthemes-element-pack'),
					];
					$s_label = isset($style_labels[ $s ]) ? $style_labels[ $s ] : $s;
					$w_label = isset($weights[ $w ]) ? $weights[ $w ] : $w;
					$w_display = in_array($w, ['normal', 'bold'], true) ? $w_label : $w;
					$w_css = $this->preview_font_weight_css($w);
					$block_state = count($font_files) > 1 ? 'ep-state-collapsed' : 'ep-state-expanded';
					?>
					<div class="ep-font-variation ep-font-variation-card ep-repeater-block <?php echo esc_attr($block_state); ?>" data-index="<?php echo esc_attr($index); ?>">
						<div class="ep-font-row-summary">
							<div class="ep-font-row-summary-meta">
								<span class="ep-font-summary-col ep-font-summary-weight">
									<span class="ep-font-summary-label"><?php esc_html_e('Weight:', 'bdthemes-element-pack'); ?></span>
									<span class="ep-font-summary-value ep-font-display-weight"><?php echo esc_html($w_display); ?></span>
								</span>
								<span class="ep-font-summary-col ep-font-summary-style">
									<span class="ep-font-summary-label"><?php esc_html_e('Style:', 'bdthemes-element-pack'); ?></span>
									<span class="ep-font-summary-value ep-font-display-style"><?php echo esc_html($s_label); ?></span>
								</span>
							</div>
							<div class="ep-font-row-summary-preview inline-preview ep-font-summary-inline-preview"
								style="<?php echo $font_family ? 'font-family: \'' . esc_attr($font_family) . '\';' : ''; ?> font-weight: <?php echo esc_attr($w_css); ?>; font-style: <?php echo esc_attr($s); ?>;">
								<?php echo esc_html($preview_raw); ?>
							</div>
							<div class="ep-font-row-summary-tools">
								<button type="button" class="button-link ep-repeater-tool-btn ep-edit-row">
									<span class="dashicons dashicons-edit" aria-hidden="true"></span>
									<?php esc_html_e('Edit', 'bdthemes-element-pack'); ?>
								</button>
								<button type="button" class="button-link ep-repeater-tool-btn ep-remove-variation remove-repeater-row" <?php echo (count($font_files) < 2) ? 'disabled' : ''; ?>>
									<span class="dashicons dashicons-trash" aria-hidden="true"></span>
									<?php esc_html_e('Delete', 'bdthemes-element-pack'); ?>
								</button>
							</div>
						</div>

						<div class="ep-repeater-expanded-bar">
							<button type="button" class="button-link ep-repeater-tool-btn ep-close-row">
								<span class="dashicons dashicons-no-alt" aria-hidden="true"></span>
								<?php esc_html_e('Close', 'bdthemes-element-pack'); ?>
							</button>
						</div>

						<div class="ep-repeater-content ep-font-repeater-content">
							<div class="repeater-content-top ep-repeater-content-top">
								<div>
									<p class="ep-field-row ep-field-weight">
										<label class="ep-font-field-label" for="ep-fw-<?php echo esc_attr($index); ?>"><?php esc_html_e('Weight:', 'bdthemes-element-pack'); ?></label>
										<select name="ep_font_files[<?php echo esc_attr($index); ?>][font_weight]" id="ep-fw-<?php echo esc_attr($index); ?>" class="ep-font-weight ep-font-select elementor-field-select" data-preview-family="<?php echo esc_attr($font_family); ?>">
											<?php
											foreach ($weights as $value => $label) {
												echo '<option value="' . esc_attr($value) . '" ' . selected($w, $value, false) . '>' . esc_html($label) . '</option>';
											}
											?>
										</select>
									</p>
								</div>
								<div>
									<p class="ep-field-row ep-field-style">
										<label class="ep-font-field-label" for="ep-fs-<?php echo esc_attr($index); ?>"><?php esc_html_e('Style:', 'bdthemes-element-pack'); ?></label>
										<select name="ep_font_files[<?php echo esc_attr($index); ?>][font_style]" id="ep-fs-<?php echo esc_attr($index); ?>" class="ep-font-style ep-font-select elementor-field-select" data-preview-family="<?php echo esc_attr($font_family); ?>">
											<option value="normal" <?php selected($s, 'normal'); ?>><?php esc_html_e('Normal', 'bdthemes-element-pack'); ?></option>
											<option value="italic" <?php selected($s, 'italic'); ?>><?php esc_html_e('Italic', 'bdthemes-element-pack'); ?></option>
											<option value="oblique" <?php selected($s, 'oblique'); ?>><?php esc_html_e('Oblique', 'bdthemes-element-pack'); ?></option>
										</select>
									</p>
								</div>
								<div class="ep-field-toolbar elementor-field-toolbar"></div>
							</div>

							<div class="inline-preview ep-font-inline-preview"
								style="<?php echo $font_family ? 'font-family: \'' . esc_attr($font_family) . '\';' : ''; ?> font-weight: <?php echo esc_attr($w_css); ?>; font-style: <?php echo esc_attr($s); ?>;"
								data-preview-base="<?php echo esc_attr($preview_raw); ?>">
								<?php echo esc_html($preview_raw); ?>
							</div>

							<div class="ep-repeater-content-bottom ep-font-files-bottom">
								<table class="form-table ep-font-files-table">
									<tbody>
									<?php
									$formats = [
										'woff'  => 'WOFF',
										'woff2' => 'WOFF2',
										'ttf'   => 'TTF',
										'otf'   => 'OTF',
										'svg'   => 'SVG',
										'eot'   => 'EOT',
									];

									foreach ($formats as $format => $abbr) :
										$label = sprintf(
											/* translators: %s: Font format, e.g. WOFF */
											__('%s File', 'bdthemes-element-pack'),
											$abbr
										);
										$file_data = isset($font_file[ $format ]) ? $font_file[ $format ] : '';
										$file_url = '';
										$file_id = '';

										if (is_array($file_data)) {
											$file_url = isset($file_data['url']) ? $file_data['url'] : '';
											$file_id = isset($file_data['id']) ? $file_data['id'] : '';
										}
										?>
										<tr class="ep-font-file-row">
											<th scope="row">
												<label><?php echo esc_html($label); ?></label>
											</th>
											<td>
												<input type="hidden"
														name="ep_font_files[<?php echo esc_attr($index); ?>][<?php echo esc_attr($format); ?>][id]"
														class="ep-font-file-id"
														value="<?php echo esc_attr($file_id); ?>">
												<input type="text"
														name="ep_font_files[<?php echo esc_attr($index); ?>][<?php echo esc_attr($format); ?>][url]"
														class="regular-text ep-font-file-url elementor-field-input"
														value="<?php echo esc_url($file_url); ?>"
														readonly>
												<button type="button"
														class="button ep-upload-font-file elementor-upload-btn"
														data-format="<?php echo esc_attr($format); ?>"
														data-index="<?php echo esc_attr($index); ?>">
													<?php esc_html_e('Upload', 'bdthemes-element-pack'); ?>
												</button>
												<?php if ($file_url) : ?>
													<button type="button" class="button ep-remove-font-file elementor-upload-clear-btn">
														<?php esc_html_e('Remove', 'bdthemes-element-pack'); ?>
													</button>
												<?php endif; ?>
											</td>
										</tr>
									<?php endforeach; ?>
									</tbody>
								</table>
							</div>
						</div>
					</div>
				<?php endforeach; ?>
			</div>

			<p class="ep-font-add-wrap">
				<button type="button" class="button button-primary ep-add-variation">
					<?php esc_html_e('Add font variation', 'bdthemes-element-pack'); ?>
				</button>
			</p>
		</div>
		<?php
	}

	/**
	 * Save meta box
	 */
	public function save_meta_box($post_id) {
		// Security checks
		if (!isset($_POST['ep_font_meta_nonce']) || !wp_verify_nonce($_POST['ep_font_meta_nonce'], 'ep_save_font_meta')) {
			return;
		}

		if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
			return;
		}

		if (!current_user_can('edit_post', $post_id)) {
			return;
		}

		// Save font files
		if (isset($_POST['ep_font_files']) && is_array($_POST['ep_font_files'])) {
			$font_files = [];

			foreach ($_POST['ep_font_files'] as $variation) {
				if (!is_array($variation)) {
					continue;
				}
				$font_data = [
					'font_weight' => isset($variation['font_weight']) ? $this->sanitize_font_weight($variation['font_weight']) : '400',
					'font_style'  => isset($variation['font_style']) ? sanitize_text_field($variation['font_style']) : 'normal',
				];

				$formats = ['woff', 'woff2', 'ttf', 'otf', 'svg', 'eot'];
				foreach ($formats as $format) {
					if (isset($variation[$format]) && is_array($variation[$format])) {
						$url = isset($variation[$format]['url']) ? esc_url_raw($variation[$format]['url']) : '';
						$id  = isset($variation[$format]['id']) ? absint($variation[$format]['id']) : 0;
						// Only save if the file matches this format (prevent TTF in WOFF2 field, etc.)
						if ($url && !$this->attachment_matches_font_format($id, $url, $format)) {
							$font_data[$format] = '';
						} else {
							$font_data[$format] = [
								'id'  => $id,
								'url' => $url,
							];
						}
					} else {
						$font_data[$format] = '';
					}
				}

				$font_files[] = $font_data;
			}

			update_post_meta($post_id, EP_Custom_Fonts_Manager::FONT_META_KEY, $font_files);
			
			// Delete cached CSS to regenerate
			delete_post_meta($post_id, EP_Custom_Fonts_Manager::FONT_FACE_META_KEY);
		}
	}

	/**
	 * Scoped styles on the font list screen (Elementor-like spacing).
	 */
	public function print_list_screen_styles() {
		$screen = get_current_screen();
		if (!$screen || $screen->post_type !== EP_Custom_Fonts_Manager::CPT || $screen->base !== 'edit') {
			return;
		}
		?>
		<style>
			.post-type-ep_custom_font .wrap .wp-heading-inline,
			.post-type-ep_custom_font .wrap h1.wp-heading-inline {
				font-size: 23px;
				font-weight: 400;
				margin-right: 8px;
			}
			.post-type-ep_custom_font .page-title-action {
				margin-left: 4px;
			}
		</style>
		<?php
	}

	/**
	 * Enqueue admin assets
	 */
	public function enqueue_admin_assets($hook) {
		$screen = get_current_screen();
		if (!$screen || $screen->post_type !== EP_Custom_Fonts_Manager::CPT) {
			return;
		}

		// Enqueue WordPress media uploader
		wp_enqueue_media();
		wp_enqueue_style('dashicons');

		// Enqueue admin styles
		wp_enqueue_style(
			'ep-custom-fonts-admin',
			EP_CUSTOM_FONTS_URL . 'assets/css/custom-fonts.css',
			[],
			BDTEP_VER
		);

		wp_enqueue_script(
			'ep-custom-fonts-admin',
			EP_CUSTOM_FONTS_URL . 'assets/js/custom-fonts.min.js',
			['jquery', 'media-upload'],
			BDTEP_VER,
			true
		);

		$uploader = EP_Font_Uploader::instance();
		$allowed_formats = [];
		foreach ($uploader->get_supported_types() as $format => $data) {
			$allowed_formats[$format] = [
				'extensions' => $data['ext'],
				'mimeType'   => explode('|', $data['mime'])[0],
			];
		}

		wp_localize_script('ep-custom-fonts-admin', 'EPCustomFontsAdmin', [
			'uploadTitle'    => esc_html__('Select Font File', 'bdthemes-element-pack'),
			'uploadButton'   => esc_html__('Use this file', 'bdthemes-element-pack'),
			'allowedFormats' => $allowed_formats,
			/* translators: %s: Allowed font file format */
			'wrongFormat'    => esc_html__('Please select a %s file for this field.', 'bdthemes-element-pack'),
			'previewText'    => __('Think Big, Act Smarter', 'bdthemes-element-pack'),
			'lblWeightColon' => __('Weight:', 'bdthemes-element-pack'),
			'lblStyleColon'  => __('Style:', 'bdthemes-element-pack'),
			'styleNormal'    => __('Normal', 'bdthemes-element-pack'),
			'styleItalic'    => __('Italic', 'bdthemes-element-pack'),
			'styleOblique'   => __('Oblique', 'bdthemes-element-pack'),
			'lblClose'       => __('Close', 'bdthemes-element-pack'),
			'lblEdit'        => __('Edit', 'bdthemes-element-pack'),
			'lblDelete'      => __('Delete', 'bdthemes-element-pack'),
			'removeLabel'    => __('Remove', 'bdthemes-element-pack'),
			'uploadBtn'      => __('Upload', 'bdthemes-element-pack'),
			/* translators: %s: Font format abbreviation (WOFF, WOFF2, …) */
			'fileLabelTpl'   => __('%s File', 'bdthemes-element-pack'),
			'lblNormal'        => __('Normal', 'bdthemes-element-pack'),
			'lblBold'          => __('Bold', 'bdthemes-element-pack'),
		]);
	}

	/**
	 * Customize columns
	 */
	public function customize_columns($columns) {
		$new_columns = [];
		$new_columns['cb'] = $columns['cb'];
		$new_columns['title'] = esc_html__('Font Family', 'bdthemes-element-pack');
		$new_columns['preview'] = esc_html__('Preview', 'bdthemes-element-pack');
		$new_columns['variations'] = esc_html__('Variations', 'bdthemes-element-pack');
		$new_columns['date'] = $columns['date'];
		return $new_columns;
	}

	/**
	 * Render custom column
	 */
	public function render_column($column, $post_id) {
		if ($column === 'preview') {
			$font_family = get_the_title($post_id);
			$font_css = EP_Custom_Fonts_Manager::instance()->get_font_face_css($font_family);
			
			if ($font_css) {
				$unique_id = 'ep-font-preview-' . $post_id;
				// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- Plugin-generated @font-face CSS (contains url()/src rules that must not be HTML-escaped).
				echo '<style>' . $font_css . '</style>';
				echo '<div class="ep-font-preview" style="font-family: \'' . esc_attr($font_family) . '\';">';
				echo esc_html__('Think Big, Act Smarter', 'bdthemes-element-pack');
				echo '</div>';
			} else {
				echo '<span class="ep-font-no-preview">' . esc_html__('No files', 'bdthemes-element-pack') . '</span>';
			}
		}
		
		if ($column === 'variations') {
			$font_files = get_post_meta($post_id, EP_Custom_Fonts_Manager::FONT_META_KEY, true);
			if (is_array($font_files)) {
				echo '<strong>' . count($font_files) . '</strong> ' . esc_html(_n('variation', 'variations', count($font_files), 'bdthemes-element-pack'));
			} else {
				echo '—';
			}
		}
	}

	/**
	 * Customize row actions
	 */
	public function customize_row_actions($actions, $post) {
		if ($post->post_type === EP_Custom_Fonts_Manager::CPT) {
			unset($actions['inline hide-if-no-js']);
			unset($actions['view']);
		}
		return $actions;
	}

	/**
	 * Check if an attachment URL/ID matches the expected font format (e.g. woff2, ttf).
	 *
	 * @param int    $attachment_id Attachment ID (optional).
	 * @param string $url           File URL.
	 * @param string $format        Expected format: woff2, woff, ttf, otf, eot, svg.
	 * @return bool
	 */
	private function attachment_matches_font_format($attachment_id, $url, $format) {
		$expected_ext = strtolower($format);
		// Check URL path extension
		$path = wp_parse_url($url, PHP_URL_PATH);
		if ($path) {
			$ext = strtolower(pathinfo($path, PATHINFO_EXTENSION));
			if ($ext === $expected_ext) {
				return true;
			}
		}
		// If we have attachment ID, check file path
		if ($attachment_id) {
			$file = get_attached_file($attachment_id);
			if ($file && file_exists($file)) {
				$ext = strtolower(pathinfo($file, PATHINFO_EXTENSION));
				return $ext === $expected_ext;
			}
		}
		return false;
	}

	/**
	 * Clear cache
	 */
	public function clear_cache() {
		EP_Custom_Fonts_Manager::instance()->clear_fonts_cache();
	}

	/**
	 * Clear cache only when a custom font post is deleted
	 *
	 * @param int      $post_id Post ID.
	 * @param \WP_Post $post    Post object.
	 */
	public function clear_cache_on_delete($post_id, $post) {
		if ($post && $post->post_type === EP_Custom_Fonts_Manager::CPT) {
			$this->clear_cache();
		}
	}
}
