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

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

class BW_Schema_Recipe extends BW_Schema_Base {
	
	/**
	 * Generate recipe schema
	 */
	public function generate( $post, $type = 'Recipe' ) {
		// Base schema
		$schema = array(
			'@context' => 'https://schema.org',
			'@type' => $type,
		);
		
		// Add common properties
		$schema = array_merge( $schema, $this->get_common_properties( $post ) );
		
		// Add author
		$schema['author'] = $this->get_author_properties( $post->post_author );
		
		// Add recipe category
		$recipe_category = get_post_meta( $post->ID, '_bw_schema_recipe_category', true );
		if ( ! empty( $recipe_category ) ) {
			$schema['recipeCategory'] = $recipe_category;
		}
		
		// Add recipe cuisine
		$recipe_cuisine = get_post_meta( $post->ID, '_bw_schema_recipe_cuisine', true );
		if ( ! empty( $recipe_cuisine ) ) {
			$schema['recipeCuisine'] = $recipe_cuisine;
		}
		
		// Add prep time
		$prep_time = get_post_meta( $post->ID, '_bw_schema_prep_time', true );
		if ( ! empty( $prep_time ) ) {
			$schema['prepTime'] = 'PT' . $prep_time . 'M';
		}
		
		// Add cook time
		$cook_time = get_post_meta( $post->ID, '_bw_schema_cook_time', true );
		if ( ! empty( $cook_time ) ) {
			$schema['cookTime'] = 'PT' . $cook_time . 'M';
		}
		
		// Add total time
		$total_time = get_post_meta( $post->ID, '_bw_schema_total_time', true );
		if ( ! empty( $total_time ) ) {
			$schema['totalTime'] = 'PT' . $total_time . 'M';
		} elseif ( ! empty( $prep_time ) && ! empty( $cook_time ) ) {
			$schema['totalTime'] = 'PT' . ( intval( $prep_time ) + intval( $cook_time ) ) . 'M';
		}
		
		// Add recipe yield
		$recipe_yield = get_post_meta( $post->ID, '_bw_schema_recipe_yield', true );
		if ( ! empty( $recipe_yield ) ) {
			$schema['recipeYield'] = $recipe_yield;
		}
		
		// Add ingredients
		$ingredients = $this->get_recipe_ingredients( $post );
		if ( ! empty( $ingredients ) ) {
			$schema['recipeIngredient'] = $ingredients;
		}
		
		// Add instructions
		$instructions = $this->get_recipe_instructions( $post );
		if ( ! empty( $instructions ) ) {
			$schema['recipeInstructions'] = $instructions;
		}
		
		// Add nutrition information
		$nutrition = $this->get_nutrition_information( $post );
		if ( ! empty( $nutrition ) ) {
			$schema['nutrition'] = $nutrition;
		}
		
		// Add aggregate rating
		$rating = $this->get_aggregate_rating( $post );
		if ( ! empty( $rating ) ) {
			$schema['aggregateRating'] = $rating;
		}
		
		// Add video
		$video = $this->get_recipe_video( $post );
		if ( ! empty( $video ) ) {
			$schema['video'] = $video;
		}
		
		// Add keywords
		$keywords = get_post_meta( $post->ID, '_bw_schema_recipe_keywords', true );
		if ( ! empty( $keywords ) ) {
			$schema['keywords'] = $keywords;
		}
		
		// Add suitable for diet
		$suitable_for_diet = get_post_meta( $post->ID, '_bw_schema_suitable_for_diet', true );
		if ( ! empty( $suitable_for_diet ) && is_array( $suitable_for_diet ) ) {
			$schema['suitableForDiet'] = array_map( function( $diet ) {
				return 'https://schema.org/' . $diet;
			}, $suitable_for_diet );
		}
		
		// Add cooking method
		$cooking_method = get_post_meta( $post->ID, '_bw_schema_cooking_method', true );
		if ( ! empty( $cooking_method ) ) {
			$schema['cookingMethod'] = $cooking_method;
		}
		
		// Add in language
		$schema['inLanguage'] = get_locale();
		
		// Add AI-optimized properties
		$schema = $this->add_ai_properties( $schema, $post );
		
		return apply_filters( 'bw_schema_recipe', $schema, $post, $type );
	}
	
	/**
	 * Get recipe ingredients
	 */
	private function get_recipe_ingredients( $post ) {
		$ingredients = get_post_meta( $post->ID, '_bw_schema_ingredients', true );
		
		if ( empty( $ingredients ) ) {
			// Try to extract from content
			$content = $post->post_content;
			preg_match_all( '/<li[^>]*class="[^"]*ingredient[^"]*"[^>]*>(.*?)<\/li>/is', $content, $matches );
			
			if ( ! empty( $matches[1] ) ) {
				return array_map( 'wp_strip_all_tags', $matches[1] );
			}
			
			return null;
		}
		
		if ( is_array( $ingredients ) ) {
			return $ingredients;
		}
		
		// If it's a string, split by new lines
		return array_filter( array_map( 'trim', explode( "\n", $ingredients ) ) );
	}
	
	/**
	 * Get recipe instructions
	 */
	private function get_recipe_instructions( $post ) {
		$instructions = get_post_meta( $post->ID, '_bw_schema_instructions', true );
		
		if ( empty( $instructions ) ) {
			// Try to extract from content
			$content = $post->post_content;
			preg_match_all( '/<li[^>]*class="[^"]*instruction[^"]*"[^>]*>(.*?)<\/li>/is', $content, $matches );
			
			if ( ! empty( $matches[1] ) ) {
				$instruction_list = array();
				foreach ( $matches[1] as $index => $instruction ) {
					$instruction_list[] = array(
						'@type' => 'HowToStep',
						'text' => wp_strip_all_tags( $instruction ),
						'position' => $index + 1,
					);
				}
				return $instruction_list;
			}
			
			return null;
		}
		
		if ( is_array( $instructions ) ) {
			$instruction_list = array();
			foreach ( $instructions as $index => $instruction ) {
				if ( is_array( $instruction ) && isset( $instruction['text'] ) ) {
					$instruction_list[] = array(
						'@type' => 'HowToStep',
						'text' => $instruction['text'],
						'name' => isset( $instruction['name'] ) ? $instruction['name'] : '',
						'position' => $index + 1,
					);
				} else {
					$instruction_list[] = array(
						'@type' => 'HowToStep',
						'text' => $instruction,
						'position' => $index + 1,
					);
				}
			}
			return $instruction_list;
		}
		
		// If it's a string, split by new lines
		$steps = array_filter( array_map( 'trim', explode( "\n", $instructions ) ) );
		$instruction_list = array();
		foreach ( $steps as $index => $step ) {
			$instruction_list[] = array(
				'@type' => 'HowToStep',
				'text' => $step,
				'position' => $index + 1,
			);
		}
		
		return $instruction_list;
	}
	
	/**
	 * Get nutrition information
	 */
	private function get_nutrition_information( $post ) {
		$nutrition = array(
			'@type' => 'NutritionInformation',
		);
		
		// Serving size
		$serving_size = get_post_meta( $post->ID, '_bw_schema_serving_size', true );
		if ( ! empty( $serving_size ) ) {
			$nutrition['servingSize'] = $serving_size;
		}
		
		// Calories
		$calories = get_post_meta( $post->ID, '_bw_schema_calories', true );
		if ( ! empty( $calories ) ) {
			$nutrition['calories'] = $calories . ' calories';
		}
		
		// Fat content
		$fat = get_post_meta( $post->ID, '_bw_schema_fat_content', true );
		if ( ! empty( $fat ) ) {
			$nutrition['fatContent'] = $fat . ' g';
		}
		
		// Saturated fat content
		$saturated_fat = get_post_meta( $post->ID, '_bw_schema_saturated_fat_content', true );
		if ( ! empty( $saturated_fat ) ) {
			$nutrition['saturatedFatContent'] = $saturated_fat . ' g';
		}
		
		// Cholesterol content
		$cholesterol = get_post_meta( $post->ID, '_bw_schema_cholesterol_content', true );
		if ( ! empty( $cholesterol ) ) {
			$nutrition['cholesterolContent'] = $cholesterol . ' mg';
		}
		
		// Sodium content
		$sodium = get_post_meta( $post->ID, '_bw_schema_sodium_content', true );
		if ( ! empty( $sodium ) ) {
			$nutrition['sodiumContent'] = $sodium . ' mg';
		}
		
		// Carbohydrate content
		$carbs = get_post_meta( $post->ID, '_bw_schema_carbohydrate_content', true );
		if ( ! empty( $carbs ) ) {
			$nutrition['carbohydrateContent'] = $carbs . ' g';
		}
		
		// Fiber content
		$fiber = get_post_meta( $post->ID, '_bw_schema_fiber_content', true );
		if ( ! empty( $fiber ) ) {
			$nutrition['fiberContent'] = $fiber . ' g';
		}
		
		// Sugar content
		$sugar = get_post_meta( $post->ID, '_bw_schema_sugar_content', true );
		if ( ! empty( $sugar ) ) {
			$nutrition['sugarContent'] = $sugar . ' g';
		}
		
		// Protein content
		$protein = get_post_meta( $post->ID, '_bw_schema_protein_content', true );
		if ( ! empty( $protein ) ) {
			$nutrition['proteinContent'] = $protein . ' g';
		}
		
		// Only return if we have nutrition data
		return count( $nutrition ) > 1 ? $nutrition : null;
	}
	
	/**
	 * Get aggregate rating
	 */
	private function get_aggregate_rating( $post ) {
		$rating_value = get_post_meta( $post->ID, '_bw_schema_rating_value', true );
		$rating_count = get_post_meta( $post->ID, '_bw_schema_rating_count', true );
		
		if ( empty( $rating_value ) || empty( $rating_count ) ) {
			// Try to get from comments
			$comments_count = get_comments_number( $post );
			if ( $comments_count > 0 ) {
				// Calculate average rating from comments if available
				$comments = get_comments( array(
					'post_id' => $post->ID,
					'status' => 'approve',
				) );
				
				$total_rating = 0;
				$rated_comments = 0;
				
				foreach ( $comments as $comment ) {
					$comment_rating = get_comment_meta( $comment->comment_ID, 'rating', true );
					if ( ! empty( $comment_rating ) ) {
						$total_rating += floatval( $comment_rating );
						$rated_comments++;
					}
				}
				
				if ( $rated_comments > 0 ) {
					$rating_value = round( $total_rating / $rated_comments, 1 );
					$rating_count = $rated_comments;
				}
			}
		}
		
		if ( empty( $rating_value ) || empty( $rating_count ) ) {
			return null;
		}
		
		return array(
			'@type' => 'AggregateRating',
			'ratingValue' => floatval( $rating_value ),
			'ratingCount' => intval( $rating_count ),
			'bestRating' => 5,
			'worstRating' => 1,
		);
	}
	
	/**
	 * Get recipe video
	 */
	private function get_recipe_video( $post ) {
		$video_url = get_post_meta( $post->ID, '_bw_schema_video_url', true );
		
		if ( empty( $video_url ) ) {
			// Try to find video in content
			$content = $post->post_content;
			preg_match( '/<iframe[^>]+src="([^"]+(?:youtube\.com|youtu\.be|vimeo\.com)[^"]+)"[^>]*>/i', $content, $matches );
			
			if ( ! empty( $matches[1] ) ) {
				$video_url = $matches[1];
			}
		}
		
		if ( empty( $video_url ) ) {
			return null;
		}
		
		$video = array(
			'@type' => 'VideoObject',
			'url' => $video_url,
		);
		
		// Add video name
		$video_name = get_post_meta( $post->ID, '_bw_schema_video_name', true );
		if ( ! empty( $video_name ) ) {
			$video['name'] = $video_name;
		} else {
			$video['name'] = get_the_title( $post ) . ' Video';
		}
		
		// Add video description
		$video_description = get_post_meta( $post->ID, '_bw_schema_video_description', true );
		if ( ! empty( $video_description ) ) {
			$video['description'] = $video_description;
		}
		
		// Add thumbnail URL
		$video_thumbnail = get_post_meta( $post->ID, '_bw_schema_video_thumbnail_url', true );
		if ( ! empty( $video_thumbnail ) ) {
			$video['thumbnailUrl'] = $video_thumbnail;
		}
		
		// Add upload date
		$video_upload_date = get_post_meta( $post->ID, '_bw_schema_video_upload_date', true );
		if ( ! empty( $video_upload_date ) ) {
			$video['uploadDate'] = $video_upload_date;
		} else {
			$video['uploadDate'] = get_the_date( 'c', $post );
		}
		
		// Add duration
		$video_duration = get_post_meta( $post->ID, '_bw_schema_video_duration', true );
		if ( ! empty( $video_duration ) ) {
			$video['duration'] = $video_duration;
		}
		
		return $video;
	}
}