<?php
/**
 * PufferGo Template Loader — 声明式模板注册表 + 自动发现变体 + 统一渲染。
 *
 * 核心职责：
 * 1. 注册页面布局（layout）并自动挂载 template_include / theme_page_templates。
 * 2. 自动发现 headers/ 和 footers/ 目录中的变体文件。
 * 3. 提供统一的 render_header() / render_footer() 方法（编辑模式 / 正常模式通用）。
 * 4. 提供 puffergo_render_component() 辅助函数，按需加载组件。
 *
 * 新增 header/footer 变体：只需在对应目录创建文件，零代码改动。
 * 新增页面布局：一次 register_layout() + 一个布局文件。
 *
 * @package PufferGo
 */

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

class PufferGo_Template_Loader {

	/** @var array<string, array> 注册的页面布局 */
	private static $layouts = array();

	/** @var array<string, array> 自动发现的 header 变体 id => ['id','file','label'] */
	private static $headers = array();

	/** @var array<string, array> 自动发现的 footer 变体 id => ['id','file','label'] */
	private static $footers = array();

	/**
	 * 内容模板变体，按页面类型分组。
	 * @var array<string, array<string, array>> e.g. ['product-single' => ['default' => [...]]]
	 */
	private static $content_templates = array();

	/** @var bool 是否已初始化 */
	private static $initialized = false;

	/**
	 * 初始化：注册布局 + 自动发现 header/footer + 挂载 WordPress 钩子。
	 */
	public static function init() {
		if ( self::$initialized ) {
			return;
		}
		self::$initialized = true;

		// 自动扫描 header / footer 变体目录
		self::$headers = self::discover_variants( 'templates/headers' );
		self::$footers = self::discover_variants( 'templates/footers' );

		// 自动扫描内容模板变体目录（每个子目录代表一种页面类型）
		self::$content_templates = self::discover_content_templates();

		// 声明式注册页面布局
		self::register_layout( 'fullpage', array(
			'label'       => __( 'PufferGo Universal Template', 'puffergo' ),
			'wp_template' => 'puffergo-fullpage.php', // 对应 WordPress Page Template 下拉值
			'file'        => 'templates/layouts/fullpage.php',
			'match'       => function () {
				if ( ! is_singular( 'page' ) ) {
					return false;
				}
				$tpl = get_post_meta( get_the_ID(), '_wp_page_template', true );
				return $tpl === 'puffergo-fullpage.php';
			},
		) );

		self::register_layout( 'product-single', array(
			'file'  => 'templates/layouts/product-single.php',
			'match' => function () {
				return is_singular( 'puffergo_product' );
			},
		) );

		self::register_layout( 'product-archive', array(
			'file'  => 'templates/layouts/product-archive.php',
			'match' => function () {
				return is_post_type_archive( 'puffergo_product' ) || is_tax( 'puffergo_product_cat' );
			},
		) );

		self::register_layout( 'blog-single', array(
			'file'  => 'templates/layouts/blog-single.php',
			'match' => function () {
				return is_singular( 'post' );
			},
		) );

		self::register_layout( 'blog-archive', array(
			'file'  => 'templates/layouts/blog-archive.php',
			'match' => function () {
				return ( is_home() && ! is_front_page() )
					|| is_post_type_archive( 'post' )
					|| is_category();
			},
		) );

		// WordPress 钩子
		add_filter( 'theme_page_templates', array( __CLASS__, 'filter_theme_page_templates' ) );
		add_filter( 'template_include', array( __CLASS__, 'filter_template_include' ), 99 );
	}

	// ─── 布局注册 ──────────────────────────────────────────────

	/**
	 * 注册一个页面布局。
	 *
	 * @param string $id   布局唯一标识。
	 * @param array  $args {
	 *   @type string   $label       在 WordPress Page Attributes 中显示的名称（可选，仅 page template 需要）。
	 *   @type string   $wp_template 对应 _wp_page_template meta 值（可选，仅 page template 需要）。
	 *   @type string   $file        布局文件的相对路径（相对于插件根目录）。
	 *   @type callable $match       返回 bool 的匹配函数，决定何时使用此布局。
	 * }
	 */
	public static function register_layout( $id, array $args ) {
		self::$layouts[ $id ] = wp_parse_args( $args, array(
			'label'       => '',
			'wp_template' => '',
			'file'        => '',
			'match'       => '__return_false',
		) );
	}

	// ─── 变体发现 ──────────────────────────────────────────────

	/**
	 * 扫描 content-templates/ 目录，按页面类型分组发现变体。
	 *
	 * 目录约定：
	 *   content-templates/
	 *     product-single/    ← 页面类型
	 *       default.php      ← 变体文件
	 *       modern.php
	 *     product-archive/
	 *       default.php
	 *       grid.php
	 *
	 * @return array<string, array<string, array>>
	 */
	private static function discover_content_templates() {
		$base_dir = PUFFERGO_PLUGIN_DIR . '/templates/content-templates';
		if ( ! is_dir( $base_dir ) ) {
			return array();
		}

		$result = array();
		foreach ( glob( $base_dir . '/*', GLOB_ONLYDIR ) as $type_dir ) {
			$page_type = basename( $type_dir );
			$result[ $page_type ] = self::discover_variants( 'templates/content-templates/' . $page_type );
		}
		return $result;
	}

	/**
	 * 扫描目录，自动发现 header/footer 变体。
	 *
	 * 约定：
	 * - 文件名即变体 ID（不含 .php 后缀）。
	 * - 文件头注释中可用 "Template Name: xxx" 指定显示名称。
	 * - 否则从文件名生成（header-default → Default）。
	 *
	 * @param string $relative_dir 相对于插件根目录的路径。
	 * @return array<string, array{id:string, file:string, label:string}>
	 */
	private static function discover_variants( $relative_dir ) {
		$dir = PUFFERGO_PLUGIN_DIR . '/' . $relative_dir;
		if ( ! is_dir( $dir ) ) {
			return array();
		}

		$variants = array();
		foreach ( glob( $dir . '/*.php' ) as $file ) {
			$id    = basename( $file, '.php' );
			$label = self::extract_template_name( $file );
			if ( ! $label ) {
				// 从文件名生成标签：header-default → Default, header-3 → Header 3
				$label = self::generate_label_from_id( $id );
			}
			$variants[ $id ] = array(
				'id'    => $id,
				'file'  => $file,
				'label' => $label,
			);
		}
		return $variants;
	}

	/**
	 * 从文件头部注释提取 Template Name。
	 *
	 * @param string $file 文件完整路径。
	 * @return string|null
	 */
	private static function extract_template_name( $file ) {
		$content = file_get_contents( $file, false, null, 0, 800 ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents
		if ( preg_match( '/Template\s*Name:\s*(.+)/i', $content, $m ) ) {
			return trim( $m[1] );
		}
		return null;
	}

	/**
	 * 从变体 ID 生成人类可读的标签。
	 *
	 * @param string $id 例如 header-default, footer-3。
	 * @return string
	 */
	private static function generate_label_from_id( $id ) {
		// 去掉已知前缀 "header-" / "footer-"
		$name = preg_replace( '/^(header|footer)-/', '', $id );
		if ( $name === $id ) {
			// 无前缀（如 content template 的 default / modern），直接美化
			return ucfirst( str_replace( '-', ' ', $id ) );
		}
		if ( is_numeric( $name ) ) {
			return 'Variant ' . $name;
		}
		return ucfirst( str_replace( '-', ' ', $name ) );
	}

	// ─── Header / Footer 渲染 ─────────────────────────────────

	/**
	 * 将变体 ID 映射为 CSS 所需的类名。
	 * header-default → puffergo-header-default
	 * header-2 → puffergo-header-variant-2
	 * header-3 → puffergo-header-variant-3
	 * footer-simple → puffergo-footer-default
	 * footer-2 → puffergo-footer-variant-2
	 * footer-3 → puffergo-footer-variant-3
	 *
	 * @param string $id       变体 ID。
	 * @param string $type     'header' 或 'footer'。
	 * @return string          CSS 类名。
	 */
	private static function variant_css_class( $id, $type ) {
		// 已知的默认变体映射
		static $map = array(
			'header-default' => 'puffergo-header-default',
			'footer-simple'  => 'puffergo-footer-default',
		);
		if ( isset( $map[ $id ] ) ) {
			return $map[ $id ];
		}
		// header-2 → puffergo-header-variant-2, footer-3 → puffergo-footer-variant-3
		$prefix = 'puffergo-' . $type . '-variant-';
		$name   = preg_replace( '/^(header|footer)-/', '', $id );
		return $prefix . $name;
	}

	/**
	 * 渲染当前选中的 header 变体（编辑模式渲染全部，正常模式只渲染选中的）。
	 * puffergo-fullpage-layout 作为 Tailwind 作用域前缀，直接合并到 variant wrap 上。
	 */
	public static function render_header() {
		self::render_variants( 'header', self::$headers, self::get_active_header() );

		// 编辑模式下渲染设计切换器（header/footer/nav-alignment 选择器）
		if ( self::is_edit_mode() ) {
			puffergo_render_component( 'design-switcher' );
		}
	}

	/**
	 * 渲染当前选中的 footer 变体（编辑模式渲染全部，正常模式只渲染选中的）。
	 * puffergo-fullpage-layout 作为 Tailwind 作用域前缀，直接合并到 variant wrap 上。
	 */
	public static function render_footer() {
		self::render_variants( 'footer', self::$footers, self::get_active_footer() );
	}

	/**
	 * 渲染变体（header 或 footer），编辑模式全部渲染，正常模式只渲染选中的。
	 *
	 * @param string $type     'header' 或 'footer'。
	 * @param array  $variants 变体列表。
	 * @param string $selected 当前选中的变体 ID。
	 */
	private static function render_variants( $type, $variants, $selected ) {
		$is_edit = self::is_edit_mode();
		$scope   = 'puffergo-fullpage-layout';
		$wrap    = 'puffergo-' . $type . '-wrap';
		$data_attr = 'data-' . $type . '-template';
		$active_class = 'puffergo-' . $type . '-active';

		if ( $is_edit && ! empty( $variants ) ) {
			foreach ( $variants as $id => $v ) {
				$data = self::create_variant_data( $type );
				$css    = self::variant_css_class( $id, $type );
				$active = ( $id === $selected ) ? ' ' . $active_class : '';
				printf(
					'<div class="%s %s %s%s" %s="%s">',
					esc_attr( $scope ),
					esc_attr( $wrap ),
					esc_attr( $css ),
					esc_attr( $active ),
					esc_attr( $data_attr ),
					esc_attr( $id )
				);
				require $v['file'];
				echo '</div>';
			}
		} elseif ( isset( $variants[ $selected ] ) ) {
			$data = self::create_variant_data( $type );
			$css = self::variant_css_class( $selected, $type );
			printf(
				'<div class="%s %s %s %s" %s="%s">',
				esc_attr( $scope ),
				esc_attr( $wrap ),
				esc_attr( $css ),
				esc_attr( $active_class ),
				esc_attr( $data_attr ),
				esc_attr( $selected )
			);
			require $variants[ $selected ]['file'];
			echo '</div>';
		}
	}

	/**
	 * 创建 header/footer 变体的数据对象。
	 *
	 * @param string $type 'header' 或 'footer'。
	 * @return PufferGo_Header_Data|PufferGo_Footer_Data|null
	 */
	private static function create_variant_data( $type ) {
		if ( 'header' === $type ) {
			require_once PUFFERGO_PLUGIN_DIR . '/templates/data/class-puffergo-header-data.php';
			return PufferGo_Header_Data::from_current_page();
		}
		if ( 'footer' === $type ) {
			require_once PUFFERGO_PLUGIN_DIR . '/templates/data/class-puffergo-footer-data.php';
			return PufferGo_Footer_Data::from_global_context();
		}
		return null;
	}

	/**
	 * 获取当前选中的 header 变体 ID。
	 *
	 * @return string
	 */
	public static function get_active_header() {
		return self::resolve_active_variant(
			get_option( 'puffergo_header_template', '' ),
			self::$headers,
			'header-default'
		);
	}

	/**
	 * 获取当前选中的 footer 变体 ID。
	 *
	 * @return string
	 */
	public static function get_active_footer() {
		return self::resolve_active_variant(
			get_option( 'puffergo_footer_template', '' ),
			self::$footers,
			'footer-simple'
		);
	}

	/**
	 * 解析当前选中的变体 ID（含旧值映射 + fallback）。
	 *
	 * @param string $selected     数据库中存储的值。
	 * @param array  $variants     可用变体列表。
	 * @param string $fallback     无任何变体时的兜底值。
	 * @return string
	 */
	private static function resolve_active_variant( $selected, $variants, $fallback ) {
		// 兼容旧值映射：header → header-default, footer → footer-simple
		$legacy_map = array(
			'header' => 'header-default',
			'footer' => 'footer-simple',
		);
		if ( isset( $legacy_map[ $selected ] ) ) {
			$selected = $legacy_map[ $selected ];
		}
		if ( isset( $variants[ $selected ] ) ) {
			return $selected;
		}
		return ! empty( $variants ) ? array_key_first( $variants ) : $fallback;
	}

	/**
	 * 判断是否处于编辑模式（管理员可编辑 + fullpage 模板）。
	 *
	 * @return bool
	 */
	public static function is_edit_mode() {
		return ! empty( $GLOBALS['puffergo_fullpage_template'] ) && current_user_can( 'edit_posts' );
	}

	// ─── WordPress 钩子 ────────────────────────────────────────

	/**
	 * 在 WordPress Page Attributes 中注册页面模板。
	 *
	 * @param array $templates 现有模板列表。
	 * @return array
	 */
	public static function filter_theme_page_templates( $templates ) {
		foreach ( self::$layouts as $layout ) {
			if ( ! empty( $layout['wp_template'] ) && ! empty( $layout['label'] ) ) {
				$templates[ $layout['wp_template'] ] = $layout['label'];
			}
		}
		return $templates;
	}

	/**
	 * template_include 过滤：匹配已注册的布局。
	 *
	 * @param string $template 当前模板路径。
	 * @return string
	 */
	public static function filter_template_include( $template ) {
		foreach ( self::$layouts as $layout ) {
			if ( is_callable( $layout['match'] ) && call_user_func( $layout['match'] ) ) {
				$file = PUFFERGO_PLUGIN_DIR . '/' . $layout['file'];
				if ( file_exists( $file ) ) {
					return $file;
				}
			}
		}
		return $template;
	}

	// ─── 公共访问器 ────────────────────────────────────────────

	/**
	 * 判断当前请求是否由 puffergo 模板布局处理。
	 *
	 * 用于脚本按需加载：任何已注册布局的 match 回调命中即返回 true。
	 * 后续新增 register_layout() 无需改动加载逻辑。
	 *
	 * @return bool
	 */
	public static function is_puffergo_template() {
		foreach ( self::$layouts as $layout ) {
			if ( is_callable( $layout['match'] ) && call_user_func( $layout['match'] ) ) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 获取所有已发现的 header 变体。
	 *
	 * @return array
	 */
	public static function get_headers() {
		return self::$headers;
	}

	/**
	 * 获取所有已发现的 footer 变体。
	 *
	 * @return array
	 */
	public static function get_footers() {
		return self::$footers;
	}

	/**
	 * 获取指定页面类型的所有内容模板变体。
	 *
	 * @param string $page_type 如 'product-single'。
	 * @return array
	 */
	public static function get_content_templates( $page_type ) {
		return self::$content_templates[ $page_type ] ?? array();
	}

	/**
	 * 获取当前选中的内容模板变体 ID。
	 *
	 * @param string $page_type 页面类型。
	 * @return string 变体 ID。
	 */
	public static function get_active_content_template( $page_type ) {
		$variants  = self::$content_templates[ $page_type ] ?? array();
		$saved     = get_option( "puffergo_template_{$page_type}", '' );

		// 编辑模式：支持预览参数 ?puffergo_preview[product-single]=modern
		if ( self::is_edit_mode() ) {
			// phpcs:ignore WordPress.Security.NonceVerification.Recommended
			$preview = isset( $_GET['puffergo_preview'][ $page_type ] )
				? sanitize_key( $_GET['puffergo_preview'][ $page_type ] ) : '';
			if ( $preview && isset( $variants[ $preview ] ) ) {
				return $preview;
			}
		}

		if ( '' !== $saved && isset( $variants[ $saved ] ) ) {
			return $saved;
		}
		return ! empty( $variants ) ? array_key_first( $variants ) : 'default';
	}

	/**
	 * 获取内容模板变体的文件路径。
	 *
	 * @param string $page_type   页面类型。
	 * @param string $variant_id  变体 ID。
	 * @return string|null 文件路径，不存在返回 null。
	 */
	public static function get_content_template_file( $page_type, $variant_id ) {
		return self::$content_templates[ $page_type ][ $variant_id ]['file'] ?? null;
	}

	/**
	 * 验证内容模板变体 ID 是否有效。
	 *
	 * @param string $page_type  页面类型。
	 * @param string $id         变体 ID。
	 * @return bool
	 */
	public static function is_valid_content_template( $page_type, $id ) {
		return isset( self::$content_templates[ $page_type ][ $id ] );
	}

	/**
	 * 验证 header 变体 ID 是否有效。
	 *
	 * @param string $id 变体 ID。
	 * @return bool
	 */
	public static function is_valid_header( $id ) {
		return isset( self::$headers[ $id ] );
	}

	/**
	 * 验证 footer 变体 ID 是否有效。
	 *
	 * @param string $id 变体 ID。
	 * @return bool
	 */
	public static function is_valid_footer( $id ) {
		return isset( self::$footers[ $id ] );
	}
}

/**
 * 渲染一个组件（templates/components/ 下的文件）。
 *
 * @param string $name 组件名称（不含 .php）。
 * @param array  $args 传递给组件的变量（key => value）。
 */
function puffergo_render_component( $name, $args = array() ) {
	$file = PUFFERGO_PLUGIN_DIR . "/templates/components/{$name}.php";
	if ( file_exists( $file ) ) {
		if ( ! empty( $args ) ) {
			extract( $args, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
		}
		require $file;
	}
}
