<?php
/**
 * Article schema type
 *
 * Outputs schema.org/BlogPosting or schema.org/NewsArticle markup for posts.
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Schema_Article extends BW_Schema_Schema_Base {

	/**
	 * Schema type (can be overridden)
	 *
	 * @var string
	 */
	protected $type = 'BlogPosting';

	/**
	 * Post object
	 *
	 * @var WP_Post
	 */
	private $post;

	/**
	 * Constructor
	 *
	 * @param WP_Post|null $post Post object
	 */
	public function __construct( $post = null ) {
		if ( null === $post ) {
			global $post;
		}

		$this->post = $post;

		// Per-post type override from the Solomon Schema metabox — must be
		// applied before parent::__construct() stamps @type via build()
		if ( $this->post && class_exists( 'BW_Schema_Metabox' ) ) {
			$override = get_post_meta( $this->post->ID, '_bw_schema_type_override', true );
			if ( '' !== $override && array_key_exists( $override, BW_Schema_Metabox::get_type_options() ) ) {
				$this->type = $override;
			}
		}

		parent::__construct();
	}

	/**
	 * Build the article schema
	 *
	 * @return void
	 */
	protected function build() {
		if ( ! $this->post ) {
			return;
		}

		try {
			// Headline (title)
			$this->set( 'headline', get_the_title( $this->post->ID ) );

			// Description
			$description = $this->get_excerpt();
			if ( $description ) {
				$this->set( 'description', $description );
			}

			// Main content body
			$this->set( 'articleBody', $this->get_body() );
		} catch ( Throwable $e ) {
			// Schema build failed, bail
			return;
		}

		// Featured image
		$this->set_image();

		// Author
		$this->set_author();

		// Date published
		$this->set( 'datePublished', $this->format_datetime( $this->post->post_date_gmt ) );

		// Date modified
		if ( $this->post->post_modified_gmt !== $this->post->post_date_gmt ) {
			$this->set( 'dateModified', $this->format_datetime( $this->post->post_modified_gmt ) );
		}

		// URL
		$this->set( 'url', get_permalink( $this->post->ID ) );

		// Category (if available)
		$this->set_category();

		// Keywords/tags
		$this->set_keywords();
	}

	/**
	 * Get post excerpt or generate from content
	 *
	 * @return string Post excerpt or empty string
	 */
	private function get_excerpt() {
		$excerpt = $this->post->post_excerpt;

		if ( $excerpt ) {
			return $this->sanitize_text( wp_strip_all_tags( $excerpt ) );
		}

		// Generate from content if no excerpt
		if ( $this->post->post_content ) {
			$content = wp_strip_all_tags( $this->post->post_content );
			// Truncate to 160 characters for description
			return $this->sanitize_text( wp_trim_words( $content, 30 ) );
		}

		return '';
	}

	/**
	 * Get post body content (stripped of tags)
	 *
	 * @return string Post content
	 */
	private function get_body() {
		return wp_strip_all_tags( $this->post->post_content );
	}

	/**
	 * Set featured image
	 *
	 * @return void
	 */
	private function set_image() {
		$image_id = get_post_thumbnail_id( $this->post->ID );

		if ( ! $image_id ) {
			return;
		}

		$image_url = wp_get_attachment_url( $image_id );

		if ( ! $image_url ) {
			return;
		}

		$image = array(
			'@type' => 'ImageObject',
			'url'   => esc_url_raw( $image_url ),
		);

		// Get image dimensions
		$attachment = get_post( $image_id );
		if ( $attachment ) {
			$meta = wp_get_attachment_metadata( $image_id );
			if ( $meta ) {
				$image['width']  = $meta['width'] ?? '';
				$image['height'] = $meta['height'] ?? '';
			}

			// Alt text
			$alt = get_post_meta( $image_id, '_wp_attachment_image_alt', true );
			if ( $alt ) {
				$image['description'] = $alt;
			}
		}

		$this->set_nested( 'image', $image );
	}

	/**
	 * Set article author
	 *
	 * @return void
	 */
	private function set_author() {
		$author_id = $this->post->post_author;

		if ( ! $author_id ) {
			return;
		}

		// Check if this post has a team member override
		$team_override = BW_Schema_Service_People::get_post_author_override( $this->post->ID );
		if ( $team_override ) {
			$this->set_team_author( $team_override );
			return;
		}

		// Use WordPress author
		$author = get_userdata( $author_id );
		if ( ! $author ) {
			return;
		}

		$author_data = array(
			'@type' => 'Person',
			'name'  => $author->display_name,
			'url'   => get_author_posts_url( $author_id ),
		);

		$this->set_nested( 'author', $author_data );
	}

	/**
	 * Set team member as author
	 *
	 * @param int $team_post_id Team member post ID
	 * @return void
	 */
	private function set_team_author( $team_post_id ) {
		$team_post = get_post( $team_post_id );

		if ( ! $team_post ) {
			return;
		}

		$author_data = array(
			'@type' => 'Person',
			'name'  => get_the_title( $team_post_id ),
			'url'   => get_permalink( $team_post_id ),
		);

		// Add team member photo if available
		$photo_id = get_post_thumbnail_id( $team_post_id );
		if ( $photo_id ) {
			$photo_url = wp_get_attachment_url( $photo_id );
			if ( $photo_url ) {
				$author_data['image'] = esc_url_raw( $photo_url );
			}
		}

		$this->set_nested( 'author', $author_data );
	}

	/**
	 * Set article category
	 *
	 * @return void
	 */
	private function set_category() {
		$categories = get_the_category( $this->post->ID );

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

		// Use the primary category
		$category = $categories[0];
		$this->set( 'articleSection', $category->name );
	}

	/**
	 * Set article keywords/tags
	 *
	 * @return void
	 */
	private function set_keywords() {
		$tags = get_the_tags( $this->post->ID );

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

		$keywords = wp_list_pluck( $tags, 'name' );
		if ( ! empty( $keywords ) ) {
			$this->set( 'keywords', implode( ', ', $keywords ) );
		}
	}

	/**
	 * Validate article schema
	 *
	 * Article requires headline and content.
	 *
	 * @return array Validation errors
	 */
	public function validate() {
		$errors = parent::validate();

		if ( ! $this->post ) {
			$errors[] = 'Article schema requires a valid post object';
			return $errors;
		}

		// Check required properties
		if ( ! $this->has_required( array( 'headline', 'articleBody' ) ) ) {
			$errors[] = 'Article schema requires headline and body content';
		}

		return $errors;
	}
}
