<?php
/**
 * Video Schema Class for BW AI Schema Pro
 *
 * @package BW_AI_Schema_Pro
 */

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

class BW_Schema_Video extends BW_Schema_Base {
	
	/**
	 * Generate video schema
	 */
	public function generate( $post, $type = 'VideoObject' ) {
		// Base schema
		$schema = array(
			'@context' => 'https://schema.org',
			'@type' => $type,
		);
		
		// Add common properties
		$schema = array_merge( $schema, $this->get_common_properties( $post ) );
		
		// Add video URL (required)
		$video_url = get_post_meta( $post->ID, '_bw_schema_video_url', true );
		if ( empty( $video_url ) ) {
			// Try to extract from content
			$video_url = $this->extract_video_url( $post->post_content );
		}
		
		if ( ! empty( $video_url ) ) {
			$schema['contentUrl'] = $video_url;
			$schema['embedUrl'] = $video_url;
		}
		
		// Add upload date
		$upload_date = get_post_meta( $post->ID, '_bw_schema_upload_date', true );
		if ( ! empty( $upload_date ) ) {
			$schema['uploadDate'] = $upload_date;
		} else {
			$schema['uploadDate'] = get_the_date( 'c', $post );
		}
		
		// Add duration
		$duration = get_post_meta( $post->ID, '_bw_schema_duration', true );
		if ( ! empty( $duration ) ) {
			$schema['duration'] = $this->format_duration( $duration );
		}
		
		// Add thumbnail
		$thumbnail_url = get_post_meta( $post->ID, '_bw_schema_thumbnail_url', true );
		if ( empty( $thumbnail_url ) && has_post_thumbnail( $post ) ) {
			$thumbnail_url = get_the_post_thumbnail_url( $post, 'full' );
		}
		
		if ( ! empty( $thumbnail_url ) ) {
			$schema['thumbnailUrl'] = array( $thumbnail_url );
		}
		
		// Add transcript
		$transcript = get_post_meta( $post->ID, '_bw_schema_transcript', true );
		if ( ! empty( $transcript ) ) {
			$schema['transcript'] = $transcript;
		}
		
		// Add video frame size
		$video_width = get_post_meta( $post->ID, '_bw_schema_video_width', true );
		$video_height = get_post_meta( $post->ID, '_bw_schema_video_height', true );
		
		if ( ! empty( $video_width ) && ! empty( $video_height ) ) {
			$schema['width'] = array(
				'@type' => 'QuantitativeValue',
				'value' => intval( $video_width ),
				'unitCode' => 'PX',
			);
			$schema['height'] = array(
				'@type' => 'QuantitativeValue',
				'value' => intval( $video_height ),
				'unitCode' => 'PX',
			);
		}
		
		// Add video quality
		$video_quality = get_post_meta( $post->ID, '_bw_schema_video_quality', true );
		if ( ! empty( $video_quality ) ) {
			$schema['videoQuality'] = $video_quality;
		}
		
		// Add encoding format
		$encoding_format = get_post_meta( $post->ID, '_bw_schema_encoding_format', true );
		if ( ! empty( $encoding_format ) ) {
			$schema['encodingFormat'] = $encoding_format;
		}
		
		// Add publisher
		$schema['publisher'] = $this->get_organization_properties();
		
		// Add creator
		$creator = $this->get_creator_properties( $post );
		if ( ! empty( $creator ) ) {
			$schema['creator'] = $creator;
		}
		
		// Add actors
		$actors = get_post_meta( $post->ID, '_bw_schema_actors', true );
		if ( ! empty( $actors ) && is_array( $actors ) ) {
			$actor_list = array();
			foreach ( $actors as $actor ) {
				$actor_list[] = array(
					'@type' => 'Person',
					'name' => $actor,
				);
			}
			$schema['actor'] = $actor_list;
		}
		
		// Add director
		$director = get_post_meta( $post->ID, '_bw_schema_director', true );
		if ( ! empty( $director ) ) {
			$schema['director'] = array(
				'@type' => 'Person',
				'name' => $director,
			);
		}
		
		// Add genre
		$genre = get_post_meta( $post->ID, '_bw_schema_genre', true );
		if ( ! empty( $genre ) ) {
			$schema['genre'] = $genre;
		}
		
		// Add interaction statistics
		$schema['interactionStatistic'] = $this->get_interaction_statistics( $post );
		
		// Add potential action
		$schema['potentialAction'] = array(
			'@type' => 'WatchAction',
			'target' => ! empty( $video_url ) ? $video_url : get_permalink( $post ),
		);
		
		// Add requires subscription
		$requires_subscription = get_post_meta( $post->ID, '_bw_schema_requires_subscription', true );
		if ( $requires_subscription === 'yes' ) {
			$schema['requiresSubscription'] = array(
				'@type' => 'MediaSubscription',
				'@id' => home_url( '/subscription' ),
			);
		}
		
		// Add is family friendly
		$family_friendly = get_post_meta( $post->ID, '_bw_schema_is_family_friendly', true );
		if ( ! empty( $family_friendly ) ) {
			$schema['isFamilyFriendly'] = $family_friendly === 'yes';
		}
		
		// Add content rating
		$content_rating = get_post_meta( $post->ID, '_bw_schema_content_rating', true );
		if ( ! empty( $content_rating ) ) {
			$schema['contentRating'] = $content_rating;
		}
		
		// Add in language
		$schema['inLanguage'] = get_locale();
		
		// Add AI-optimized properties
		$schema = $this->add_ai_properties( $schema, $post );
		
		// Add video segments/clips
		$segments = $this->get_video_segments( $post );
		if ( ! empty( $segments ) ) {
			$schema['hasPart'] = $segments;
		}
		
		// Add specific properties based on video type
		switch ( $type ) {
			case 'Movie':
				$schema = $this->add_movie_properties( $schema, $post );
				break;
				
			case 'TVEpisode':
				$schema = $this->add_tv_episode_properties( $schema, $post );
				break;
				
			case 'MusicVideoObject':
				$schema = $this->add_music_video_properties( $schema, $post );
				break;
		}
		
		return apply_filters( 'bw_schema_video', $schema, $post, $type );
	}
	
	/**
	 * Extract video URL from content
	 */
	private function extract_video_url( $content ) {
		// YouTube
		preg_match( '/(?:https?:\/\/)?(?:www\.)?(?:youtube\.com\/(?:embed\/|watch\?v=)|youtu\.be\/)([a-zA-Z0-9_-]+)/', $content, $youtube_matches );
		if ( ! empty( $youtube_matches[1] ) ) {
			return 'https://www.youtube.com/watch?v=' . $youtube_matches[1];
		}
		
		// Vimeo
		preg_match( '/(?:https?:\/\/)?(?:www\.)?vimeo\.com\/([0-9]+)/', $content, $vimeo_matches );
		if ( ! empty( $vimeo_matches[1] ) ) {
			return 'https://vimeo.com/' . $vimeo_matches[1];
		}
		
		// Video tag
		preg_match( '/<video[^>]+src="([^"]+)"/', $content, $video_matches );
		if ( ! empty( $video_matches[1] ) ) {
			return $video_matches[1];
		}
		
		return '';
	}
	
	/**
	 * Format duration to ISO 8601
	 */
	private function format_duration( $duration ) {
		// If already in ISO 8601 format
		if ( strpos( $duration, 'PT' ) === 0 ) {
			return $duration;
		}
		
		// If in seconds
		if ( is_numeric( $duration ) ) {
			$hours = floor( $duration / 3600 );
			$minutes = floor( ( $duration % 3600 ) / 60 );
			$seconds = $duration % 60;
			
			$formatted = 'PT';
			if ( $hours > 0 ) {
				$formatted .= $hours . 'H';
			}
			if ( $minutes > 0 ) {
				$formatted .= $minutes . 'M';
			}
			if ( $seconds > 0 ) {
				$formatted .= $seconds . 'S';
			}
			
			return $formatted;
		}
		
		// If in HH:MM:SS format
		if ( preg_match( '/(\d+):(\d+):(\d+)/', $duration, $matches ) ) {
			$hours = intval( $matches[1] );
			$minutes = intval( $matches[2] );
			$seconds = intval( $matches[3] );
			
			$formatted = 'PT';
			if ( $hours > 0 ) {
				$formatted .= $hours . 'H';
			}
			if ( $minutes > 0 ) {
				$formatted .= $minutes . 'M';
			}
			if ( $seconds > 0 ) {
				$formatted .= $seconds . 'S';
			}
			
			return $formatted;
		}
		
		return $duration;
	}
	
	/**
	 * Get creator properties
	 */
	private function get_creator_properties( $post ) {
		$creator_type = get_post_meta( $post->ID, '_bw_schema_creator_type', true );
		$creator_name = get_post_meta( $post->ID, '_bw_schema_creator_name', true );
		
		if ( empty( $creator_name ) ) {
			return $this->get_author_properties( $post->post_author );
		}
		
		$creator = array(
			'@type' => $creator_type === 'organization' ? 'Organization' : 'Person',
			'name' => $creator_name,
		);
		
		$creator_url = get_post_meta( $post->ID, '_bw_schema_creator_url', true );
		if ( ! empty( $creator_url ) ) {
			$creator['url'] = $creator_url;
		}
		
		return $creator;
	}
	
	/**
	 * Get interaction statistics
	 */
	private function get_interaction_statistics( $post ) {
		$statistics = array();
		
		// View count
		$view_count = get_post_meta( $post->ID, '_bw_schema_view_count', true );
		if ( ! empty( $view_count ) ) {
			$statistics[] = array(
				'@type' => 'InteractionCounter',
				'interactionType' => 'https://schema.org/WatchAction',
				'userInteractionCount' => intval( $view_count ),
			);
		}
		
		// Like count
		$like_count = get_post_meta( $post->ID, '_bw_schema_like_count', true );
		if ( ! empty( $like_count ) ) {
			$statistics[] = array(
				'@type' => 'InteractionCounter',
				'interactionType' => 'https://schema.org/LikeAction',
				'userInteractionCount' => intval( $like_count ),
			);
		}
		
		// Comment count
		$comment_count = get_comments_number( $post );
		if ( $comment_count > 0 ) {
			$statistics[] = array(
				'@type' => 'InteractionCounter',
				'interactionType' => 'https://schema.org/CommentAction',
				'userInteractionCount' => $comment_count,
			);
		}
		
		// Share count
		$share_count = get_post_meta( $post->ID, '_bw_schema_share_count', true );
		if ( ! empty( $share_count ) ) {
			$statistics[] = array(
				'@type' => 'InteractionCounter',
				'interactionType' => 'https://schema.org/ShareAction',
				'userInteractionCount' => intval( $share_count ),
			);
		}
		
		return $statistics;
	}
	
	/**
	 * Get video segments
	 */
	private function get_video_segments( $post ) {
		$segments = get_post_meta( $post->ID, '_bw_schema_video_segments', true );
		
		if ( empty( $segments ) || ! is_array( $segments ) ) {
			return null;
		}
		
		$segment_list = array();
		foreach ( $segments as $segment ) {
			$clip = array(
				'@type' => 'Clip',
			);
			
			if ( ! empty( $segment['name'] ) ) {
				$clip['name'] = $segment['name'];
			}
			
			if ( ! empty( $segment['startOffset'] ) ) {
				$clip['startOffset'] = intval( $segment['startOffset'] );
			}
			
			if ( ! empty( $segment['endOffset'] ) ) {
				$clip['endOffset'] = intval( $segment['endOffset'] );
			}
			
			if ( ! empty( $segment['description'] ) ) {
				$clip['description'] = $segment['description'];
			}
			
			if ( ! empty( $segment['url'] ) ) {
				$clip['url'] = $segment['url'];
			}
			
			$segment_list[] = $clip;
		}
		
		return $segment_list;
	}
	
	/**
	 * Add movie specific properties
	 */
	private function add_movie_properties( $schema, $post ) {
		// Production company
		$production_company = get_post_meta( $post->ID, '_bw_schema_production_company', true );
		if ( ! empty( $production_company ) ) {
			$schema['productionCompany'] = array(
				'@type' => 'Organization',
				'name' => $production_company,
			);
		}
		
		// Country of origin
		$country_of_origin = get_post_meta( $post->ID, '_bw_schema_country_of_origin', true );
		if ( ! empty( $country_of_origin ) ) {
			$schema['countryOfOrigin'] = array(
				'@type' => 'Country',
				'name' => $country_of_origin,
			);
		}
		
		// Date created
		$date_created = get_post_meta( $post->ID, '_bw_schema_date_created', true );
		if ( ! empty( $date_created ) ) {
			$schema['dateCreated'] = $date_created;
		}
		
		return $schema;
	}
	
	/**
	 * Add TV episode specific properties
	 */
	private function add_tv_episode_properties( $schema, $post ) {
		// Episode number
		$episode_number = get_post_meta( $post->ID, '_bw_schema_episode_number', true );
		if ( ! empty( $episode_number ) ) {
			$schema['episodeNumber'] = intval( $episode_number );
		}
		
		// Season number
		$season_number = get_post_meta( $post->ID, '_bw_schema_season_number', true );
		if ( ! empty( $season_number ) ) {
			$schema['partOfSeason'] = array(
				'@type' => 'TVSeason',
				'seasonNumber' => intval( $season_number ),
			);
		}
		
		// Series
		$series_name = get_post_meta( $post->ID, '_bw_schema_series_name', true );
		if ( ! empty( $series_name ) ) {
			$schema['partOfSeries'] = array(
				'@type' => 'TVSeries',
				'name' => $series_name,
			);
		}
		
		return $schema;
	}
	
	/**
	 * Add music video specific properties
	 */
	private function add_music_video_properties( $schema, $post ) {
		// Music by
		$music_by = get_post_meta( $post->ID, '_bw_schema_music_by', true );
		if ( ! empty( $music_by ) ) {
			$schema['musicBy'] = array(
				'@type' => 'MusicGroup',
				'name' => $music_by,
			);
		}
		
		// Music album
		$album = get_post_meta( $post->ID, '_bw_schema_music_album', true );
		if ( ! empty( $album ) ) {
			$schema['inAlbum'] = array(
				'@type' => 'MusicAlbum',
				'name' => $album,
			);
		}
		
		// Music genre
		$genre = get_post_meta( $post->ID, '_bw_schema_music_genre', true );
		if ( ! empty( $genre ) ) {
			$schema['genre'] = $genre;
		}
		
		return $schema;
	}
}