<?php
/**
 * TitanCart Template Loader.
 *
 * Handles storefront template resolution with a WooCommerce-style
 * override system:
 *
 *   1. Check active theme: {theme}/titancart/{template}.php
 *   2. Fall back to: {plugin}/templates/{template}.php
 *
 * Usage:
 *   TitanCart\Storefront\TemplateLoader::get_template( 'product/single.php', $data );
 *
 * @package TitanCart\Storefront
 */

namespace TitanCart\Storefront;

defined( 'ABSPATH' ) || exit;

class TemplateLoader {

    /** Subdirectory within the active theme to check first. */
    const THEME_DIR = 'titancart';

    /** Plugin's default templates directory. */
    const PLUGIN_TEMPLATE_DIR = TITANCART_PATH . 'templates/';

    /**
     * Locate and load a template file, passing $data to it.
     *
     * @param string              $template  Relative path, e.g. 'product/single.php'.
     * @param array<string,mixed> $data      Variables to extract into template scope.
     * @param bool                $return    If true, return output instead of echoing.
     * @return string Rendered HTML (only if $return = true).
     */
    public static function get_template( string $template, array $data = [], bool $return = false ): string {
        $file = self::locate( $template );

        if ( ! $file ) {
            return '';
        }

        if ( $return ) {
            ob_start();
        }

        extract( $data, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract
        include $file;

        return $return ? ob_get_clean() : '';
    }

    /**
     * Shorthand alias for get_template().
     *
     * @param string              $template  Relative path.
     * @param array<string,mixed> $data      Variables to extract.
     * @param bool                $return    Return instead of echo.
     * @return string
     */
    public static function get( string $template, array $data = [], bool $return = false ): string {
        return self::get_template( $template, $data, $return );
    }

    /**
     * Locate the template file, applying the theme override system.
     *
     * @param  string $template Relative path.
     * @return string|null Absolute path if found, null otherwise.
     */
    public static function locate( string $template ): ?string {
        // Allow addons to short-circuit template resolution.
        $override = apply_filters( 'titancart_template_override', null, $template );
        if ( $override ) {
            return $override;
        }

        // 1. Active theme's titancart/ subdirectory.
        $theme_file = get_stylesheet_directory() . '/' . self::THEME_DIR . '/' . $template;
        if ( file_exists( $theme_file ) ) {
            return $theme_file;
        }

        // 2. Parent theme (if child theme active).
        $parent_theme_file = get_template_directory() . '/' . self::THEME_DIR . '/' . $template;
        if ( file_exists( $parent_theme_file ) ) {
            return $parent_theme_file;
        }

        // 3. Plugin default.
        $plugin_file = self::PLUGIN_TEMPLATE_DIR . $template;
        if ( file_exists( $plugin_file ) ) {
            return $plugin_file;
        }

        // Not found — log warning in debug mode.
        titancart_log( "TitanCart: Template not found: {$template}" );

        return null;
    }

    /**
     * Register a custom template page for a given query var value.
     * Used to serve storefront pages (shop, product, cart, checkout).
     *
     * @param string $query_var  The query var (e.g. 'tc_product').
     * @param string $template   Template to load (e.g. 'product/single.php').
     */
    public static function register_page( string $query_var, string $template ): void {
        add_filter( 'template_include', function ( string $current_template ) use ( $query_var, $template ) {
            if ( ! get_query_var( $query_var ) ) {
                return $current_template;
            }

            $file = self::locate( $template );
            return $file ?: $current_template;
        } );
    }
}
