<?php
/**
 * Event schema type
 *
 * Outputs schema.org/Event markup for event listings.
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Schema_Event extends BW_Schema_Schema_Base {

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

	/**
	 * Event data
	 *
	 * @var array|WP_Post
	 */
	private $event;

	/**
	 * Constructor
	 *
	 * @param WP_Post|array $event Event post or data array
	 */
	public function __construct( $event = null ) {
		if ( is_numeric( $event ) ) {
			$this->event = get_post( $event );
		} else {
			$this->event = $event;
		}

		parent::__construct();
	}

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

		if ( is_a( $this->event, 'WP_Post' ) ) {
			$this->build_from_post();
		} elseif ( is_array( $this->event ) ) {
			$this->build_from_array();
		}
	}

	/**
	 * Build from post object
	 *
	 * @return void
	 */
	private function build_from_post() {
		$post = $this->event;

		// Event name
		$this->set( 'name', get_the_title( $post->ID ) );

		// Description
		if ( $post->post_excerpt ) {
			$this->set( 'description', wp_strip_all_tags( $post->post_excerpt ) );
		} elseif ( $post->post_content ) {
			$this->set( 'description', wp_trim_words( wp_strip_all_tags( $post->post_content ), 30 ) );
		}

		// Image
		if ( has_post_thumbnail( $post->ID ) ) {
			$image_url = wp_get_attachment_url( get_post_thumbnail_id( $post->ID ) );
			if ( $image_url ) {
				$this->set_nested( 'image', array(
					'@type' => 'ImageObject',
					'url'   => esc_url_raw( $image_url ),
				));
			}
		}

		// Start/end dates (from post meta)
		$start_date = get_post_meta( $post->ID, '_event_start_date', true );
		if ( $start_date ) {
			$this->set( 'startDate', $this->format_datetime( $start_date ) );
		}

		$end_date = get_post_meta( $post->ID, '_event_end_date', true );
		if ( $end_date ) {
			$this->set( 'endDate', $this->format_datetime( $end_date ) );
		}

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

		// Location (if available)
		$location = get_post_meta( $post->ID, '_event_location', true );
		if ( $location ) {
			$this->set( 'location', $location );
		}
	}

	/**
	 * Build from array data
	 *
	 * @return void
	 */
	private function build_from_array() {
		$event = $this->event;

		// Name
		if ( ! empty( $event['name'] ) ) {
			$this->set( 'name', $event['name'] );
		}

		// Description
		if ( ! empty( $event['description'] ) ) {
			$this->set( 'description', $event['description'] );
		}

		// Dates
		if ( ! empty( $event['start_date'] ) ) {
			$this->set( 'startDate', $this->format_datetime( $event['start_date'] ) );
		}

		if ( ! empty( $event['end_date'] ) ) {
			$this->set( 'endDate', $this->format_datetime( $event['end_date'] ) );
		}

		// URL
		if ( ! empty( $event['url'] ) ) {
			$this->set( 'url', $this->sanitize_url( $event['url'] ) );
		}

		// Location
		if ( ! empty( $event['location'] ) ) {
			$this->set( 'location', $event['location'] );
		}
	}

	/**
	 * Validate event schema
	 *
	 * @return array Validation errors
	 */
	public function validate() {
		$errors = parent::validate();

		if ( ! $this->has_required( array( 'name' ) ) ) {
			$errors[] = 'Event schema requires a name';
		}

		// Start date recommended
		if ( ! isset( $this->schema['startDate'] ) ) {
			// Not an error but recommended
		}

		return $errors;
	}
}
