<?php
/**
 * NewsArticle schema type
 *
 * Outputs schema.org/NewsArticle markup for news posts.
 * Extends Article with news-specific features.
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Schema_NewsArticle extends BW_Schema_Schema_Article {

	/**
	 * Schema type override
	 *
	 * @var string
	 */
	protected $type = 'NewsArticle';

	/**
	 * Build the news article schema
	 *
	 * Extends parent Article schema with news-specific fields.
	 *
	 * @return void
	 */
	protected function build() {
		// First, build parent Article schema
		parent::build();

		// Get post for news-specific data
		$post = get_post( $this->get_post_id() );
		if ( ! $post ) {
			return;
		}

		// News-specific fields
		$this->add_news_specific_data( $post );
	}

	/**
	 * Get post ID from schema
	 *
	 * Helper to extract post ID from article schema.
	 *
	 * @return int Post ID
	 */
	private function get_post_id() {
		// Try to extract from schema URL
		$url = $this->schema['url'] ?? '';
		if ( $url ) {
			$post_id = url_to_postid( $url );
			if ( $post_id ) {
				return $post_id;
			}
		}

		return get_the_ID();
	}

	/**
	 * Add news-specific fields to schema
	 *
	 * @param WP_Post $post Post object
	 * @return void
	 */
	private function add_news_specific_data( $post ) {
		// Headline (primary difference from BlogPosting)
		// In NewsArticle, headline is more emphasized
		if ( ! isset( $this->schema['headline'] ) ) {
			$this->set( 'headline', get_the_title( $post->ID ) );
		}

		// Byline (optional but recommended for news)
		// Include author name and photo
		if ( isset( $this->schema['author'] ) ) {
			// Author already set in parent
		}

		// Article body (in NewsArticle this is more prominent)
		// Already set by parent, but ensure it's there
		if ( ! isset( $this->schema['articleBody'] ) && $post->post_content ) {
			$this->set( 'articleBody', wp_strip_all_tags( $post->post_content ) );
		}

		// Publication info
		$this->set_publication_info( $post );

		// News source (optional)
		if ( ! empty( get_bloginfo( 'name' ) ) ) {
			$source = array(
				'@type' => 'Organization',
				'name'  => get_bloginfo( 'name' ),
				'url'   => get_bloginfo( 'url' ),
				'logo'  => array(
					'@type' => 'ImageObject',
					'url'   => get_site_icon_url(),
				),
			);

			// Only set if we have a URL
			if ( ! empty( $source['url'] ) ) {
				// NewsArticle doesn't have "source", but it has author which can be an org
				// This is handled by parent class
			}
		}
	}

	/**
	 * Set publication info
	 *
	 * @param WP_Post $post Post object
	 * @return void
	 */
	private function set_publication_info( $post ) {
		// Publication name
		$publication = array(
			'@type' => 'Organization',
			'name'  => get_bloginfo( 'name' ),
		);

		if ( ! empty( get_bloginfo( 'url' ) ) ) {
			$publication['url'] = get_bloginfo( 'url' );
		}

		if ( ! empty( get_site_icon_url() ) ) {
			$publication['logo'] = array(
				'@type' => 'ImageObject',
				'url'   => get_site_icon_url(),
			);
		}

		// Only set if we have enough info
		if ( ! empty( $publication['name'] ) ) {
			// NewsArticle uses "isPartOf" to reference the publication
			// Or we can add it as a custom property
			$this->set( 'isPartOf', $publication );
		}
	}

	/**
	 * Validate news article schema
	 *
	 * NewsArticle has stricter requirements than BlogPosting.
	 *
	 * @return array Validation errors
	 */
	public function validate() {
		$errors = parent::validate();

		// NewsArticle requires headline (already checked by parent)
		// and datePublished (already checked by parent)

		// Additional news-specific validation
		if ( ! isset( $this->schema['author'] ) || empty( $this->schema['author'] ) ) {
			// Author is recommended for news articles
			// Not an error, but good to have
		}

		return $errors;
	}
}
