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

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

class BW_Schema_HowTo extends BW_Schema_Base {
	
	/**
	 * Generate HowTo schema
	 */
	public function generate( $post, $type = 'HowTo' ) {
		// 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 estimated cost
		$estimated_cost = $this->get_estimated_cost( $post );
		if ( ! empty( $estimated_cost ) ) {
			$schema['estimatedCost'] = $estimated_cost;
		}
		
		// Add supply
		$supply = $this->get_supply_list( $post );
		if ( ! empty( $supply ) ) {
			$schema['supply'] = $supply;
		}
		
		// Add tool
		$tools = $this->get_tool_list( $post );
		if ( ! empty( $tools ) ) {
			$schema['tool'] = $tools;
		}
		
		// Add steps (required)
		$steps = $this->get_howto_steps( $post );
		if ( ! empty( $steps ) ) {
			$schema['step'] = $steps;
		}
		
		// Add total time
		$total_time = get_post_meta( $post->ID, '_bw_schema_total_time', true );
		if ( ! empty( $total_time ) ) {
			$schema['totalTime'] = $this->format_duration( $total_time );
		}
		
		// Add prep time
		$prep_time = get_post_meta( $post->ID, '_bw_schema_prep_time', true );
		if ( ! empty( $prep_time ) ) {
			$schema['prepTime'] = $this->format_duration( $prep_time );
		}
		
		// Add perform time
		$perform_time = get_post_meta( $post->ID, '_bw_schema_perform_time', true );
		if ( ! empty( $perform_time ) ) {
			$schema['performTime'] = $this->format_duration( $perform_time );
		}
		
		// Add yield
		$yield = get_post_meta( $post->ID, '_bw_schema_yield', true );
		if ( ! empty( $yield ) ) {
			$schema['yield'] = array(
				'@type' => 'QuantitativeValue',
				'value' => $yield,
			);
		}
		
		// Add video
		$video = $this->get_howto_video( $post );
		if ( ! empty( $video ) ) {
			$schema['video'] = $video;
		}
		
		// Add aggregate rating
		$rating = $this->get_aggregate_rating( $post );
		if ( ! empty( $rating ) ) {
			$schema['aggregateRating'] = $rating;
		}
		
		// Add keywords
		$keywords = get_post_meta( $post->ID, '_bw_schema_keywords', true );
		if ( ! empty( $keywords ) ) {
			$schema['keywords'] = $keywords;
		}
		
		// Add skill level
		$skill_level = get_post_meta( $post->ID, '_bw_schema_skill_level', true );
		if ( ! empty( $skill_level ) ) {
			$schema['educationalLevel'] = $skill_level;
		}
		
		// Add category
		$category = get_post_meta( $post->ID, '_bw_schema_howto_category', true );
		if ( ! empty( $category ) ) {
			$schema['category'] = $category;
		}
		
		// Add in language
		$schema['inLanguage'] = get_locale();
		
		// Add AI-optimized properties
		$schema = $this->add_ai_properties( $schema, $post );
		
		// Add potential action
		$schema['potentialAction'] = array(
			'@type' => 'FollowAction',
			'target' => get_permalink( $post ),
		);
		
		return apply_filters( 'bw_schema_howto', $schema, $post, $type );
	}
	
	/**
	 * Get estimated cost
	 */
	private function get_estimated_cost( $post ) {
		$cost_min = get_post_meta( $post->ID, '_bw_schema_cost_min', true );
		$cost_max = get_post_meta( $post->ID, '_bw_schema_cost_max', true );
		$cost_currency = get_post_meta( $post->ID, '_bw_schema_cost_currency', true );
		
		if ( empty( $cost_min ) && empty( $cost_max ) ) {
			return null;
		}
		
		$cost = array(
			'@type' => 'MonetaryAmount',
		);
		
		if ( ! empty( $cost_currency ) ) {
			$cost['currency'] = $cost_currency;
		} else {
			$cost['currency'] = 'USD';
		}
		
		if ( ! empty( $cost_min ) && ! empty( $cost_max ) ) {
			$cost['minValue'] = floatval( $cost_min );
			$cost['maxValue'] = floatval( $cost_max );
		} elseif ( ! empty( $cost_min ) ) {
			$cost['value'] = floatval( $cost_min );
		} elseif ( ! empty( $cost_max ) ) {
			$cost['value'] = floatval( $cost_max );
		}
		
		return $cost;
	}
	
	/**
	 * Get supply list
	 */
	private function get_supply_list( $post ) {
		$supplies = get_post_meta( $post->ID, '_bw_schema_supplies', true );
		
		if ( empty( $supplies ) ) {
			// Try to extract from content
			$content = $post->post_content;
			preg_match_all( '/<li[^>]*class="[^"]*(?:supply|material|ingredient)[^"]*"[^>]*>(.*?)<\/li>/is', $content, $matches );
			
			if ( ! empty( $matches[1] ) ) {
				$supplies = array_map( 'wp_strip_all_tags', $matches[1] );
			}
		}
		
		if ( empty( $supplies ) || ! is_array( $supplies ) ) {
			return null;
		}
		
		$supply_list = array();
		foreach ( $supplies as $supply ) {
			if ( is_array( $supply ) && isset( $supply['name'] ) ) {
				$supply_item = array(
					'@type' => 'HowToSupply',
					'name' => $supply['name'],
				);
				
				if ( ! empty( $supply['quantity'] ) ) {
					$supply_item['requiredQuantity'] = array(
						'@type' => 'QuantitativeValue',
						'value' => $supply['quantity'],
					);
				}
				
				if ( ! empty( $supply['url'] ) ) {
					$supply_item['url'] = $supply['url'];
				}
				
				$supply_list[] = $supply_item;
			} else {
				$supply_list[] = array(
					'@type' => 'HowToSupply',
					'name' => $supply,
				);
			}
		}
		
		return $supply_list;
	}
	
	/**
	 * Get tool list
	 */
	private function get_tool_list( $post ) {
		$tools = get_post_meta( $post->ID, '_bw_schema_tools', true );
		
		if ( empty( $tools ) ) {
			// Try to extract from content
			$content = $post->post_content;
			preg_match_all( '/<li[^>]*class="[^"]*tool[^"]*"[^>]*>(.*?)<\/li>/is', $content, $matches );
			
			if ( ! empty( $matches[1] ) ) {
				$tools = array_map( 'wp_strip_all_tags', $matches[1] );
			}
		}
		
		if ( empty( $tools ) || ! is_array( $tools ) ) {
			return null;
		}
		
		$tool_list = array();
		foreach ( $tools as $tool ) {
			if ( is_array( $tool ) && isset( $tool['name'] ) ) {
				$tool_item = array(
					'@type' => 'HowToTool',
					'name' => $tool['name'],
				);
				
				if ( ! empty( $tool['url'] ) ) {
					$tool_item['url'] = $tool['url'];
				}
				
				$tool_list[] = $tool_item;
			} else {
				$tool_list[] = array(
					'@type' => 'HowToTool',
					'name' => $tool,
				);
			}
		}
		
		return $tool_list;
	}
	
	/**
	 * Get HowTo steps
	 */
	private function get_howto_steps( $post ) {
		$steps = get_post_meta( $post->ID, '_bw_schema_steps', true );
		
		if ( empty( $steps ) ) {
			// Try to extract from content
			$steps = $this->extract_steps_from_content( $post->post_content );
		}
		
		if ( empty( $steps ) || ! is_array( $steps ) ) {
			return null;
		}
		
		$step_list = array();
		$position = 1;
		
		foreach ( $steps as $step ) {
			if ( is_array( $step ) ) {
				// Check if this is a section
				if ( isset( $step['type'] ) && $step['type'] === 'section' ) {
					$section = array(
						'@type' => 'HowToSection',
						'position' => $position++,
					);
					
					if ( ! empty( $step['name'] ) ) {
						$section['name'] = $step['name'];
					}
					
					if ( ! empty( $step['steps'] ) && is_array( $step['steps'] ) ) {
						$section_steps = array();
						foreach ( $step['steps'] as $sub_step ) {
							$section_steps[] = $this->format_step( $sub_step, $position++ );
						}
						$section['itemListElement'] = $section_steps;
					}
					
					$step_list[] = $section;
				} else {
					// Regular step
					$step_list[] = $this->format_step( $step, $position++ );
				}
			} else {
				// Simple text step
				$step_list[] = array(
					'@type' => 'HowToStep',
					'text' => $step,
					'position' => $position++,
				);
			}
		}
		
		return $step_list;
	}
	
	/**
	 * Format a single step
	 */
	private function format_step( $step, $position ) {
		$step_item = array(
			'@type' => 'HowToStep',
			'position' => $position,
		);
		
		if ( is_array( $step ) ) {
			if ( ! empty( $step['name'] ) ) {
				$step_item['name'] = $step['name'];
			}
			
			if ( ! empty( $step['text'] ) ) {
				$step_item['text'] = $step['text'];
			} elseif ( ! empty( $step['description'] ) ) {
				$step_item['text'] = $step['description'];
			}
			
			if ( ! empty( $step['url'] ) ) {
				$step_item['url'] = $step['url'];
			}
			
			if ( ! empty( $step['image'] ) ) {
				$step_item['image'] = $step['image'];
			}
			
			if ( ! empty( $step['video'] ) ) {
				$step_item['video'] = array(
					'@type' => 'VideoObject',
					'url' => $step['video'],
				);
			}
			
			if ( ! empty( $step['tip'] ) ) {
				$step_item['tip'] = array(
					'@type' => 'HowToTip',
					'text' => $step['tip'],
				);
			}
			
			if ( ! empty( $step['direction'] ) ) {
				$step_item['direction'] = array(
					'@type' => 'HowToDirection',
					'text' => $step['direction'],
				);
			}
		} else {
			$step_item['text'] = $step;
		}
		
		return $step_item;
	}
	
	/**
	 * Extract steps from content
	 */
	private function extract_steps_from_content( $content ) {
		$steps = array();
		
		// Pattern 1: Ordered list
		preg_match_all( '/<ol[^>]*>(.*?)<\/ol>/is', $content, $ol_matches );
		
		if ( ! empty( $ol_matches[1] ) ) {
			foreach ( $ol_matches[1] as $list ) {
				preg_match_all( '/<li[^>]*>(.*?)<\/li>/is', $list, $li_matches );
				
				if ( ! empty( $li_matches[1] ) ) {
					foreach ( $li_matches[1] as $item ) {
						$steps[] = wp_strip_all_tags( $item );
					}
				}
			}
		}
		
		// Pattern 2: Headings with content
		if ( empty( $steps ) ) {
			preg_match_all( '/<h[34][^>]*>(?:Step\s*\d+[:\.]?\s*)?(.*?)<\/h[34]>(.*?)(?=<h[34]|$)/is', $content, $h_matches );
			
			if ( ! empty( $h_matches[1] ) && ! empty( $h_matches[2] ) ) {
				foreach ( $h_matches[1] as $index => $heading ) {
					$step_content = trim( $h_matches[2][$index] );
					
					if ( ! empty( $heading ) && ! empty( $step_content ) ) {
						$steps[] = array(
							'name' => wp_strip_all_tags( $heading ),
							'text' => wp_strip_all_tags( $step_content ),
						);
					}
				}
			}
		}
		
		// Pattern 3: Divs with step class
		if ( empty( $steps ) ) {
			preg_match_all( '/<div[^>]*class="[^"]*step[^"]*"[^>]*>(.*?)<\/div>/is', $content, $div_matches );
			
			if ( ! empty( $div_matches[1] ) ) {
				foreach ( $div_matches[1] as $step_content ) {
					// Try to extract title and content
					preg_match( '/<(?:h\d|strong|b)[^>]*>(.*?)<\/(?:h\d|strong|b)>(.*)$/is', $step_content, $parts );
					
					if ( ! empty( $parts[1] ) && ! empty( $parts[2] ) ) {
						$steps[] = array(
							'name' => wp_strip_all_tags( $parts[1] ),
							'text' => wp_strip_all_tags( $parts[2] ),
						);
					} else {
						$steps[] = wp_strip_all_tags( $step_content );
					}
				}
			}
		}
		
		return $steps;
	}
	
	/**
	 * 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 minutes
		if ( is_numeric( $duration ) ) {
			return 'PT' . $duration . 'M';
		}
		
		// If contains "minutes" or "hours"
		if ( preg_match( '/(\d+)\s*(minutes?|hours?)/', $duration, $matches ) ) {
			$value = intval( $matches[1] );
			$unit = $matches[2];
			
			if ( strpos( $unit, 'hour' ) !== false ) {
				return 'PT' . $value . 'H';
			} else {
				return 'PT' . $value . 'M';
			}
		}
		
		return $duration;
	}
	
	/**
	 * Get HowTo video
	 */
	private function get_howto_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['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'] = $this->format_duration( $video_duration );
		}
		
		return $video;
	}
	
	/**
	 * 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 ) ) {
			return null;
		}
		
		return array(
			'@type' => 'AggregateRating',
			'ratingValue' => floatval( $rating_value ),
			'ratingCount' => intval( $rating_count ),
			'bestRating' => 5,
			'worstRating' => 1,
		);
	}
}