<?php

/**
 * Control for typography
 *
 * @package Kubelio\Customizer
 * @since 1.0.0
 */

namespace Kubelio\Customizer;

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

class Typography {

	use Helper;

	/**
	 * Constructor.
	 */
	public function __construct() {
		add_action('after_setup_theme', array($this, 'register_fields'), 20);
	}

	/**
	 * Register Typography related customizer fields
	 */
	public function register_fields() {
		$this->set_section();
		$this->add_typography();
	}

	/**
	 * Set section
	 */
	public function set_section() {
		$this->add_section(
			'general_typography',
			array(
				'title'    => esc_html__('Typography', 'kubelio'),
				'panel'    => 'general',
				'priority' => 10,
			)
		);
	}

	/**
	 * Add typography fields
	 */
	public function add_typography() {
		$section  = 'general_typography';
		$defaults = kubelio_get_theme('typography');

		$this->add_field(
			array(
				'type'     => 'typography',
				'settings' => 'typography_heading',
				'label'    => esc_html__('Headings', 'kubelio'),
				'section'  => $section,
				'default'  => $defaults['heading'],
				'output'   => array(
					array(
						'choice'        => 'font-family',
						'element'       => ':root',
						'property'      => '--wp--preset--font-family--heading',
						'value_pattern' => $this->font_fallback_pattern('typography_heading', $defaults['heading']),
					),
					array(
						'choice'   => 'variant',
						'element'  => 'h1, h2, h3, h4, h5, h6',
						'property' => 'font-weight',
					),
				),
			)
		);

		$this->add_field(
			array(
				'type'     => 'divider',
				'settings' => 'divider_' . uniqid(),
				'section'  => $section,
			)
		);

		$this->add_field(
			array(
				'type'     => 'typography',
				'settings' => 'typography_body',
				'label'    => esc_html__('Body', 'kubelio'),
				'section'  => $section,
				'default'  => $defaults['body'],
				'output'   => array(
					array(
						'choice'        => 'font-family',
						'element'       => ':root',
						'property'      => '--wp--preset--font-family--body',
						'value_pattern' => $this->font_fallback_pattern('typography_body', $defaults['body']),
					),
					array(
						'choice'   => 'variant',
						'element'  => 'body',
						'property' => 'font-weight',
					),
				),
			)
		);

		$this->add_field(
			array(
				'type'     => 'divider',
				'settings' => 'divider_' . uniqid(),
				'section'  => $section,
			)
		);

		$this->add_field(
			array(
				'type'     => 'typography',
				'settings' => 'typography_navigation',
				'label'    => esc_html__('Primary Navigation', 'kubelio'),
				'section'  => $section,
				'default'  => $defaults['menu'],
				'output'   => array(
					array(
						'choice'        => 'font-family',
						'element'       => '.site-header .rt-menu, .site-header-mobile .rt-menu',
						'property'      => 'font-family',
						'value_pattern' => $this->font_fallback_pattern('typography_navigation', $defaults['menu']),
					),
					array(
						'choice'   => 'variant',
						'element'  => '.site-header .rt-menu, .site-header-mobile .rt-menu',
						'property' => 'font-weight',
					),
				),
			)
		);
	}

	/**
	 * Build a Kirki value_pattern that appends a generic font fallback.
	 *
	 * The fallback is chosen to match the selected font's category (e.g. a serif
	 * font falls back to `serif`, a script font to `cursive`) so the fallback text
	 * shown during webfont load resembles the final font and minimizes the visible
	 * swap (FOUT). Resolved from the currently saved value at registration time.
	 *
	 * @param string $setting The theme_mod key for the typography control.
	 * @param array  $default The default typography value.
	 * @return string Value pattern, e.g. "$, serif".
	 */
	private function font_fallback_pattern($setting, $default) {
		$value  = get_theme_mod($setting, $default);
		$family = is_array($value) && ! empty($value['font-family']) ? $value['font-family'] : '';

		return '$, ' . $this->generic_fallback($family);
	}

	/**
	 * Map a font family to its generic CSS fallback keyword.
	 *
	 * Uses the Google Fonts category when available; locally hosted or unknown
	 * fonts default to `sans-serif`.
	 *
	 * @param string $family Font family name.
	 * @return string One of: serif, sans-serif, monospace, cursive.
	 */
	private function generic_fallback($family) {
		$category = '';

		if ($family !== '' && class_exists('\Kirki\Module\Webfonts\Fonts')) {
			$google = \Kirki\Module\Webfonts\Fonts::get_google_fonts();
			if (isset($google[$family]['category'])) {
				$category = $google[$family]['category'];
			}
		}

		$map = array(
			'serif'       => 'serif',
			'sans-serif'  => 'sans-serif',
			'display'     => 'sans-serif',
			'handwriting' => 'cursive',
			'monospace'   => 'monospace',
		);

		return isset($map[$category]) ? $map[$category] : 'sans-serif';
	}
}
