<?php
/**
 * Schema.org JSON-LD: Article, Organization, BreadcrumbList.
 *
 * @package Brainwerk SEO Suite
 */

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

class Seoforge_Schema {

    public static function register( Seoforge_Loader $loader ) {
        if ( ! Seoforge_Settings::get( 'seo_schema_enabled', true ) ) {
            return;
        }
        if ( Seoforge_Compat::should_stand_down() ) {
            return;
        }
        $loader->add_action( 'wp_head', __CLASS__, 'render', 5 );
    }

    public static function render() {
        if ( is_admin() || is_feed() ) {
            return;
        }
        $graph = array();

        $org = self::organization();
        if ( $org ) {
            $graph[] = $org;
        }

        $website = self::website();
        if ( $website ) {
            $graph[] = $website;
        }

        if ( is_singular( array( 'post' ) ) ) {
            $article = self::article( get_queried_object() );
            if ( $article ) {
                $graph[] = $article;
            }
        }

        // FAQPage (Generative Engine Optimization) — built from per-post Q&A.
        if ( is_singular() && Seoforge_Settings::get( 'seo_schema_faq_enabled', true ) ) {
            $faq = self::faq( get_queried_object_id() );
            if ( $faq ) {
                $graph[] = $faq;
            }
        }

        if ( Seoforge_Settings::get( 'seo_breadcrumbs_enabled', true ) && ! is_front_page() ) {
            $crumbs = self::breadcrumbs();
            if ( $crumbs ) {
                $graph[] = $crumbs;
            }
        }

        if ( empty( $graph ) ) {
            return;
        }

        $payload = array(
            '@context' => 'https://schema.org',
            '@graph'   => $graph,
        );
        // wp_json_encode() escapes forward slashes by default (to \/), so a
        // value containing the closing-script sequence cannot break out of this
        // inline ld+json block. The escaped slash and \uXXXX remain valid JSON-LD.
        echo '<script type="application/ld+json">' . wp_json_encode( $payload ) . "</script>\n";
    }

    private static function organization() {
        $opts = (array) Seoforge_Settings::get( 'seo_schema_organization', array() );
        if ( empty( $opts['name'] ) ) {
            return null;
        }
        $node = array(
            '@type' => 'Organization',
            '@id'   => home_url( '/#organization' ),
            'name'  => $opts['name'],
            'url'   => ! empty( $opts['url'] ) ? $opts['url'] : home_url( '/' ),
        );
        if ( ! empty( $opts['logo'] ) ) {
            $node['logo'] = array(
                '@type' => 'ImageObject',
                'url'   => $opts['logo'],
            );
        }
        return $node;
    }

    private static function website() {
        return array(
            '@type'    => 'WebSite',
            '@id'      => home_url( '/#website' ),
            'url'      => home_url( '/' ),
            'name'     => get_bloginfo( 'name' ),
            'inLanguage' => get_locale(),
        );
    }

    private static function article( $post ) {
        if ( ! $post ) {
            return null;
        }
        $author = get_user_by( 'id', $post->post_author );
        $node   = array(
            '@type'         => 'Article',
            '@id'           => get_permalink( $post ) . '#article',
            'headline'      => get_the_title( $post ),
            'datePublished' => mysql2date( 'c', $post->post_date_gmt, false ),
            'dateModified'  => mysql2date( 'c', $post->post_modified_gmt, false ),
            'mainEntityOfPage' => get_permalink( $post ),
            'publisher'     => array( '@id' => home_url( '/#organization' ) ),
        );
        if ( $author ) {
            $node['author'] = array(
                '@type' => 'Person',
                'name'  => $author->display_name,
            );
        }
        $thumb = get_the_post_thumbnail_url( $post, 'large' );
        if ( $thumb ) {
            $node['image'] = $thumb;
        }
        // Speakable — helps voice assistants read the headline + summary aloud.
        $node['speakable'] = array(
            '@type'       => 'SpeakableSpecification',
            'cssSelector' => array( 'h1', '.entry-content' ),
        );
        return $node;
    }

    /**
     * FAQPage built from per-post Q&A pairs stored in `_seoforge_faq`.
     *
     * @param int $post_id
     * @return array|null
     */
    private static function faq( $post_id ) {
        $pairs = get_post_meta( $post_id, '_seoforge_faq', true );
        if ( empty( $pairs ) || ! is_array( $pairs ) ) {
            return null;
        }
        $entities = array();
        foreach ( $pairs as $p ) {
            $q = isset( $p['q'] ) ? trim( wp_strip_all_tags( (string) $p['q'] ) ) : '';
            $a = isset( $p['a'] ) ? trim( wp_strip_all_tags( (string) $p['a'] ) ) : '';
            if ( '' === $q || '' === $a ) {
                continue;
            }
            $entities[] = array(
                '@type'          => 'Question',
                'name'           => $q,
                'acceptedAnswer' => array(
                    '@type' => 'Answer',
                    'text'  => $a,
                ),
            );
        }
        if ( empty( $entities ) ) {
            return null;
        }
        return array(
            '@type'      => 'FAQPage',
            '@id'        => get_permalink( $post_id ) . '#faq',
            'mainEntity' => $entities,
        );
    }

    private static function breadcrumbs() {
        $items = array();
        $position = 1;

        $items[] = array(
            '@type'    => 'ListItem',
            'position' => $position++,
            'name'     => __( 'Home', 'brainwerk-seo-suite' ),
            'item'     => home_url( '/' ),
        );

        if ( is_singular( 'post' ) ) {
            $cats = get_the_category();
            if ( $cats ) {
                $items[] = array(
                    '@type'    => 'ListItem',
                    'position' => $position++,
                    'name'     => $cats[0]->name,
                    'item'     => get_category_link( $cats[0]->term_id ),
                );
            }
        }
        if ( is_singular() ) {
            $items[] = array(
                '@type'    => 'ListItem',
                'position' => $position++,
                'name'     => get_the_title(),
                'item'     => get_permalink(),
            );
        } elseif ( is_category() || is_tag() || is_tax() ) {
            $term = get_queried_object();
            $items[] = array(
                '@type'    => 'ListItem',
                'position' => $position++,
                'name'     => $term->name,
                'item'     => get_term_link( $term ),
            );
        }
        if ( count( $items ) <= 1 ) {
            return null;
        }
        return array(
            '@type'           => 'BreadcrumbList',
            'itemListElement' => $items,
        );
    }
}
