<?php
/**
 * Frontend Renderer
 * Fix #18: file-mtime asset versioning
 * Fix #20: FAQ schema validation before output
 *
 * @package EPWF\PublicFacing
 */
namespace EPWF\PublicFacing;

use EPWF\Includes\Settings;
use EPWF\Includes\FAQ_Manager;

defined( 'ABSPATH' ) || exit;

class Frontend {

    /** @var Settings */
    private $s;
    /** @var FAQ_Manager */
    private $m;

    public function __construct( Settings $s, FAQ_Manager $m ) {
        $this->s = $s;
        $this->m = $m;
    }

    // Fix #18: file-mtime versioning
    public function assets() {
        if ( ! is_product() || ! $this->s->is_enabled() ) return;

        $css_file = EPWF_PATH . 'assets/css/frontend.css';
        $js_file  = EPWF_PATH . 'assets/js/frontend.js';
        $css_ver  = file_exists( $css_file ) ? filemtime( $css_file ) : EPWF_VERSION;
        $js_ver   = file_exists( $js_file )  ? filemtime( $js_file )  : EPWF_VERSION;

        wp_enqueue_style( 'epwf-front', EPWF_ASSETS_URL . 'css/frontend.css', [], $css_ver );
        wp_enqueue_script( 'epwf-front', EPWF_ASSETS_URL . 'js/frontend.js', [], $js_ver, true );

        // Inject CSS custom properties from saved settings
        wp_add_inline_style( 'epwf-front', sprintf(
            ':root{--epwf-primary:%s;--epwf-hover:%s;--epwf-active:%s;--epwf-text:%s;--epwf-bg:%s;--epwf-border:%s;--epwf-answer-bg:%s;--epwf-fs:%dpx;--epwf-qfs:%dpx;--epwf-afs:%dpx;}'
            . '.epwf-wrap{margin-top:%dpx!important;margin-bottom:%dpx!important;}'
            . '.epwf-wrap .epwf-q{font-size:%dpx!important;padding:%dpx %dpx!important;}'
            . '.epwf-wrap .epwf-answer-inner{font-size:%dpx!important;padding:%dpx %dpx!important;}'
            . '.epwf-wrap .epwf-item{margin-bottom:%dpx!important;}',
            esc_attr( $this->s->get_color( 'color_primary' ) ),
            esc_attr( $this->s->get_color( 'color_hover' ) ),
            esc_attr( $this->s->get_color( 'color_active' ) ),
            esc_attr( $this->s->get_color( 'color_text' ) ),
            esc_attr( $this->s->get_color( 'color_bg' ) ),
            esc_attr( $this->s->get_color( 'color_border' ) ),
            esc_attr( $this->s->get_color( 'color_answer_bg' ) ),
            $this->s->get_font_size(),
            $this->s->get_question_font_size(),
            $this->s->get_answer_font_size(),
            $this->s->get_wrap_margin_top(),
            $this->s->get_wrap_margin_bottom(),
            $this->s->get_question_font_size(),
            $this->s->get_item_padding_v(),
            $this->s->get_item_padding_h(),
            $this->s->get_answer_font_size(),
            $this->s->get_answer_padding_v(),
            $this->s->get_answer_padding_h(),
            $this->s->get_item_margin_bottom()
        ) );
    }

    /**
     * Shortcode handler: [productfaq_ai] or [productfaq_ai id="123"]
     *
     * Attributes:
     *   id      (int)    — product ID. Defaults to current post/product.
     *   style   (string) — modern|minimal|boxed. Overrides global setting.
     *   title   (string) — custom heading text.
     *
     * @param array $atts
     * @return string  HTML output (empty string if no FAQs found)
     */
    public function render_shortcode( $atts ) {
        if ( ! $this->s->is_enabled() ) return '';

        $atts = shortcode_atts(
            [
                'id'    => 0,
                'style' => '',
                'title' => '',
            ],
            $atts,
            'productfaq_ai'
        );

        // Resolve product ID
        $pid = absint( $atts['id'] );
        if ( ! $pid ) {
            $pid = $this->get_pid();
        }
        if ( ! $pid ) return '';

        if ( ! $this->m->is_enabled( $pid ) ) return '';

        $faqs = apply_filters( 'epwf_display_faqs', $this->m->get_display_faqs( $pid ), $pid );
        $faqs = $this->validate_faqs( $faqs );
        if ( empty( $faqs ) ) return '';

        // Style: attribute → global setting → fallback 'modern'
        $allowed_styles = [ 'modern', 'minimal', 'boxed' ];
        $style = in_array( $atts['style'], $allowed_styles, true )
            ? $atts['style']
            : ( in_array( $this->s->get_style(), $allowed_styles, true ) ? $this->s->get_style() : 'modern' );

        // Title: attribute → global setting
        $title = '' !== $atts['title']
            ? sanitize_text_field( $atts['title'] )
            : apply_filters( 'epwf_section_title', $this->s->get_section_title(), $pid );

        // Ensure frontend assets are loaded (important if shortcode used outside product template)
        $this->assets();

        ob_start();
        $this->render_html( $faqs, $style, $title );
        return ob_get_clean();
    }

    public function render() {
        if ( ! is_product() || ! $this->s->is_enabled() ) return;

        $pid = $this->get_pid();
        if ( ! $pid || ! $this->m->is_enabled( $pid ) ) return;

        $faqs = apply_filters( 'epwf_display_faqs', $this->m->get_display_faqs( $pid ), $pid );
        $faqs = $this->validate_faqs( $faqs );
        if ( empty( $faqs ) ) return;

        $style = in_array( $this->s->get_style(), [ 'modern', 'minimal', 'boxed' ], true )
            ? $this->s->get_style() : 'modern';

        $title = apply_filters( 'epwf_section_title', $this->s->get_section_title(), $pid );
        $this->render_html( $faqs, $style, $title );
        if ( $this->s->is_schema_enabled() ) {
            $this->output_schema( $faqs );
        }
    }

    // ── Shared HTML renderer (used by render() and render_shortcode()) ────────

    private function render_html( $faqs, $style, $title ) {
        ?>
        <div class="epwf-wrap epwf-<?php echo esc_attr( $style ); ?>"<?php echo $this->s->is_schema_enabled() ? ' itemscope itemtype="https://schema.org/FAQPage"' : ''; ?>>
            <h2 class="epwf-heading"><?php echo esc_html( $title ); ?></h2>
            <div class="epwf-accordion" role="list">
                <?php foreach ( $faqs as $i => $faq ) : ?>
                <div class="epwf-item" role="listitem"<?php echo $this->s->is_schema_enabled() ? ' itemscope itemprop="mainEntity" itemtype="https://schema.org/Question"' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static string ?>>
                    <button class="epwf-q" type="button"
                        aria-expanded="<?php echo esc_attr( 0 === $i ? 'true' : 'false' ); ?>"
                        aria-controls="epwf-a-<?php echo absint( $i ); ?>"
                        itemprop="name">
                        <span class="epwf-q-text"><?php echo esc_html( $faq['question'] ); ?></span>
                        <span class="epwf-chevron" aria-hidden="true">
                            <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M6 9l6 6 6-6" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"/>
                            </svg>
                        </span>
                    </button>
                    <div id="epwf-a-<?php echo absint( $i ); ?>"
                        class="epwf-answer"
                        role="region"
                        itemscope itemprop="acceptedAnswer" itemtype="https://schema.org/Answer"
                        <?php echo 0 !== $i ? 'hidden' : ''; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped -- static string ?>>
                        <div class="epwf-answer-inner" itemprop="text">
                            <?php echo wp_kses_post( $faq['answer'] ); ?>
                        </div>
                    </div>
                </div>
                <?php endforeach; ?>
            </div>
        </div>
        <?php
    }

    // Fix #20: validate FAQs before rendering schema
    private function validate_faqs( $faqs ) {
        if ( ! is_array( $faqs ) ) return [];
        $valid = [];
        foreach ( $faqs as $item ) {
            if ( ! is_array( $item ) ) continue;
            $q = isset( $item['question'] ) ? trim( wp_strip_all_tags( (string) $item['question'] ) ) : '';
            $a = isset( $item['answer'] )   ? trim( (string) $item['answer'] ) : '';
            if ( mb_strlen( $q ) < 3 || mb_strlen( $a ) < 3 ) continue;
            $valid[] = [
                'question' => $q,
                'answer'   => $a,
            ];
        }
        return $valid;
    }

    // Fix #20: schema only outputs when FAQs are valid
    private function output_schema( $faqs ) {
        if ( empty( $faqs ) ) return;

        $entities = [];
        foreach ( $faqs as $faq ) {
            $q = sanitize_text_field( $faq['question'] );
            $a = sanitize_textarea_field( wp_strip_all_tags( $faq['answer'] ) );
            if ( '' === $q || '' === $a ) continue;
            $entities[] = [
                '@type'          => 'Question',
                'name'           => $q,
                'acceptedAnswer' => [ '@type' => 'Answer', 'text' => $a ],
            ];
        }

        if ( empty( $entities ) ) return;

        $schema = apply_filters( 'epwf_schema', [
            '@context'   => 'https://schema.org',
            '@type'      => 'FAQPage',
            'mainEntity' => $entities,
        ] );

        $json = wp_json_encode( $schema, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT );
        if ( $json ) {
            // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
            printf( '<script type="application/ld+json">%s</script>' . "\n", $json );
        }
    }

    private function get_pid() {
        global $product, $post;
        if ( $product instanceof \WC_Product ) return $product->get_id();
        if ( $post instanceof \WP_Post )       return $post->ID;
        return 0;
    }
}
