<?php

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

class Vserpb_Brand {

    private $name;
    private $logo;
    private $product_id;
    private $term; // WP_Term or null

    public function __construct( $product_id ) {
        $this->product_id = $product_id;
        $this->setBrandData( $product_id );
    }

    /**
     * Populate brand data (name, logo, term)
     * If no brand on product, fall back to site name / site logo / site tagline
     */
    private function setBrandData( $product_id ) {

        $brand_terms = wp_get_post_terms( $product_id, 'product_brand' );

        if ( ! empty( $brand_terms ) && ! is_wp_error( $brand_terms ) ) {
            $this->term = $brand_terms[0];
            $this->name = sanitize_text_field( $this->term->name );

            // Logo thumbnail ID stored by WP taxonomy UI (if provided)
            $thumb_id = get_term_meta( $this->term->term_id, 'thumbnail_id', true );

            if ( $thumb_id ) {
                $this->logo = wp_get_attachment_image_url( $thumb_id, 'full' );
            }

            // If term has no logo, we will attempt other fallbacks later
        }

        // Fallbacks when brand not present or brand missing values
        if ( empty( $this->name ) ) {
            // Use site name as brand name fallback
            $this->name = get_bloginfo( 'name' );
        }

        if ( empty( $this->logo ) ) {
            // Try theme custom logo
            $custom_logo_id = get_theme_mod( 'custom_logo' );
            if ( $custom_logo_id ) {
                $logo_url = wp_get_attachment_image_url( $custom_logo_id, 'full' );
                if ( $logo_url ) {
                    $this->logo = $logo_url;
                }
            }

            // Last fallback: site icon (favicon) as a URL
            if ( empty( $this->logo ) && function_exists( 'get_site_icon_url' ) ) {
                $icon_url = get_site_icon_url();
                if ( $icon_url ) {
                    $this->logo = $icon_url;
                }
            }
        }
    }

    /**
     * Return aggregate rating information for the brand (or site-wide fallback)
     * Will compute average rating and total review count from all product reviews
     * that belong to the brand. If no brand is present, uses all product reviews in the store.
     *
     * @return array ['average' => float, 'count' => int, 'reviews' => array]
     */
    private function computeBrandRatingAndReviews( $limit_reviews = 5 ) {
        global $wpdb;

        $product_ids = array();

        if ( ! empty( $this->term ) && ! is_wp_error( $this->term ) ) {
            // Get all product IDs that have this brand term
            $posts = get_posts( array(
                'post_type'      => 'product',
                'posts_per_page' => -1,
                'fields'         => 'ids',
                'tax_query'      => array(
                    array(
                        'taxonomy' => 'product_brand',
                        'field'    => 'term_id',
                        'terms'    => $this->term->term_id,
                    ),
                ),
            ) );

            if ( $posts ) {
                $product_ids = $posts;
            }
        }

        // If no brand products or no brand, fallback to all product IDs
        if ( empty( $product_ids ) ) {
            $all_products = get_posts( array(
                'post_type'      => 'product',
                'posts_per_page' => -1,
                'fields'         => 'ids',
            ) );

            $product_ids = $all_products ? $all_products : array();
        }

        $average = 0.0;
        $count   = 0;
        $reviews = array();

        if ( ! empty( $product_ids ) ) {
            // Get approved comments (reviews) for these products
            $comments = get_comments( array(
                'post__in'       => $product_ids,
                'status'         => 'approve',
                'number'         => 0, // get all
                'post_type'      => 'product',
            ) );

            $sum = 0;
            foreach ( $comments as $comment ) {
                // WooCommerce stores rating in comment meta 'rating'
                $rating = get_comment_meta( $comment->comment_ID, 'rating', true );
                $rating = $rating !== '' ? floatval( $rating ) : null;

                if ( $rating !== null ) {
                    $sum += $rating;
                    $count++;

                    // collect a small set of review objects (limit by $limit_reviews)
                    if ( count( $reviews ) < $limit_reviews ) {
                        $reviews[] = array(
                            '@type'       => 'Review',
                            'author'      => array(
                                '@type' => 'Person',
                                'name'  => get_comment_author( $comment->comment_ID ),
                            ),
                            'datePublished' => get_comment_date( 'c', $comment->comment_ID ),
                            'reviewBody'    => wp_strip_all_tags( $comment->comment_content ),
                            'reviewRating'  => array(
                                '@type'       => 'Rating',
                                'ratingValue' => $rating,
                            ),
                        );
                    }
                }
            }

            if ( $count > 0 ) {
                $average = round( $sum / $count, 2 );
            }
        }

        return array(
            'average' => $average,
            'count'   => $count,
            'reviews' => $reviews,
        );
    }

    /**
     * Build final Brand schema array
     * - includes fallback behavior described: brand-specific values when available,
     *   otherwise site/store fallbacks
     */
    public function getSchema() {

        if ( empty( $this->name ) ) {
            return array();
        }

        $schema = array(
            '@type' => 'Brand',
            'name'  => $this->name,
        );

        if ( ! empty( $this->logo ) ) {
            $schema['logo'] = esc_url( $this->logo );
        }

        // If the term has a description or tagline, use it as slogan. Otherwise use site tagline
        $slogan = '';
        if ( ! empty( $this->term ) && ! is_wp_error( $this->term ) ) {
            $slogan = trim( wp_strip_all_tags( $this->term->description ) );
        }
        if ( empty( $slogan ) ) {
            $slogan = get_bloginfo( 'description' );
        }

        if ( ! empty( $slogan ) ) {
            $schema['slogan'] = wp_strip_all_tags( $slogan );
        }

        // Get aggregate rating and a few reviews (brand-specific when possible, otherwise store-wide)
        $rating_data = $this->computeBrandRatingAndReviews( 5 );

   
        return $schema;
    }
}
