<?php
/**
 * DESCRIPTION: Locates and renders plugin PHP templates with theme-override
 * DESCRIPTION: support — the single source of truth for template resolution.
 *
 * @package NemtlyBooking
 * @since   PBOOKING_SINCE
 */

namespace NemtlyBooking\Core;

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

/**
 * Template locator and renderer.
 *
 * Resolves a template path with WooCommerce-style overriding (child theme →
 * parent theme → plugin default) and renders it to a string with a scoped set
 * of variables. The classic template loader and every shortcode use this so
 * the resolution rules, the `nemtly_booking_template_path` filter, and the
 * output-buffering render live in exactly one place.
 *
 * @since PBOOKING_SINCE
 */
class Template {

    /**
     * Folder name a theme uses to override plugin templates.
     *
     * A theme overrides any template by placing a matching file under
     * `wp-content/themes/<theme>/nemtly-booking/`.
     *
     * @since PBOOKING_SINCE
     *
     * @var string
     */
    const THEME_DIR = 'nemtly-booking';

    /**
     * Resolve a template path: child theme → parent theme → plugin default.
     *
     * The theme-override path and the value passed to the
     * `nemtly_booking_template_path` filter are both `$template` verbatim. The
     * plugin's own default lives under `templates/`, optionally nested in
     * `$plugin_subdir` — this lets the plugin store, e.g., classic templates in
     * `templates/classic/` while a theme still overrides them at the root of
     * its `nemtly-booking/` folder.
     *
     * @since PBOOKING_SINCE
     *
     * @param string $template      Template path relative to the theme override
     *                              dir, e.g. 'single-nemtly_event.php' or
     *                              'shortcodes/single-event.php'.
     * @param string $plugin_subdir Optional subdir under `templates/` for the
     *                              plugin default copy, e.g. 'classic'.
     *
     * @return string Absolute path to the template to load.
     */
    public static function locate( string $template, string $plugin_subdir = '' ): string {
        $theme_template = locate_template( [ self::THEME_DIR . '/' . $template ] );

        if ( $theme_template ) {
            $path = $theme_template;
        } else {
            $relative = $plugin_subdir ? trailingslashit( $plugin_subdir ) . $template : $template;
            $path     = NEMTLY_BOOKING_PATH . 'templates/' . $relative;
        }

        /**
         * Filter the resolved template path.
         *
         * @since PBOOKING_SINCE
         *
         * @param string $path     Absolute template path.
         * @param string $template Template path relative to the theme override dir.
         */
        return apply_filters( 'nemtly_booking_template_path', $path, $template );
    }

    /**
     * Render a template to a string with a scoped set of variables.
     *
     * @since PBOOKING_SINCE
     *
     * @param string $template      Template path relative to the theme override
     *                              dir, e.g. 'shortcodes/single-event.php'.
     * @param array  $vars          Variables exposed to the template scope.
     * @param string $plugin_subdir Optional subdir under `templates/` for the
     *                              plugin default copy, e.g. 'classic'.
     *
     * @return string Rendered HTML, or empty string when the template is unreadable.
     */
    public static function render( string $template, array $vars = [], string $plugin_subdir = '' ): string {
        $path = self::locate( $template, $plugin_subdir );

        if ( ! is_readable( $path ) ) {
            return '';
        }

        extract( $vars, EXTR_SKIP ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract -- Standard template variable pattern, keys are developer-controlled.

        ob_start();
        include $path;
        return ob_get_clean();
    }
}
