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

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

class BW_Schema_FAQ extends BW_Schema_Base {
	
	/**
	 * Generate FAQ schema
	 */
	public function generate( $post, $type = 'FAQPage' ) {
		// Base schema
		$schema = array(
			'@context' => 'https://schema.org',
			'@type' => $type,
		);
		
		// Add common properties
		$schema = array_merge( $schema, $this->get_common_properties( $post ) );
		
		// Add main entity (the FAQ items)
		$faq_items = $this->get_faq_items( $post );
		if ( ! empty( $faq_items ) ) {
			$schema['mainEntity'] = $faq_items;
		}
		
		// Add author
		$schema['author'] = $this->get_author_properties( $post->post_author );
		
		// Add publisher
		$schema['publisher'] = $this->get_organization_properties();
		
		// Add subject
		$subject = get_post_meta( $post->ID, '_bw_schema_faq_subject', true );
		if ( ! empty( $subject ) ) {
			$schema['about'] = array(
				'@type' => 'Thing',
				'name' => $subject,
			);
		}
		
		// Add categories
		$categories = get_the_category( $post->ID );
		if ( ! empty( $categories ) ) {
			$category_names = array();
			foreach ( $categories as $category ) {
				$category_names[] = $category->name;
			}
			$schema['keywords'] = implode( ', ', $category_names );
		}
		
		// Add breadcrumb
		$schema['breadcrumb'] = $this->get_breadcrumb_list( $post );
		
		// Add in language
		$schema['inLanguage'] = get_locale();
		
		// Add last reviewed
		$last_reviewed = get_post_meta( $post->ID, '_bw_schema_last_reviewed', true );
		if ( ! empty( $last_reviewed ) ) {
			$schema['lastReviewed'] = $last_reviewed;
		}
		
		// Add AI-optimized properties
		$schema = $this->add_ai_properties( $schema, $post );
		
		// Add potential action (search action for FAQ)
		$schema['potentialAction'] = array(
			'@type' => 'SearchAction',
			'target' => get_permalink( $post ) . '?search={search_term_string}',
			'query-input' => 'required name=search_term_string',
		);
		
		return apply_filters( 'bw_schema_faq', $schema, $post, $type );
	}
	
	/**
	 * Get FAQ items
	 */
	private function get_faq_items( $post ) {
		$faq_items = get_post_meta( $post->ID, '_bw_schema_faq_items', true );
		
		if ( empty( $faq_items ) ) {
			// Try to extract from content
			$faq_items = $this->extract_faq_from_content( $post->post_content );
		}
		
		if ( empty( $faq_items ) || ! is_array( $faq_items ) ) {
			return null;
		}
		
		$questions = array();
		foreach ( $faq_items as $index => $item ) {
			$question = array(
				'@type' => 'Question',
			);
			
			// Add question name
			if ( ! empty( $item['question'] ) ) {
				$question['name'] = wp_strip_all_tags( $item['question'] );
			} else {
				continue; // Skip if no question
			}
			
			// Add answer
			if ( ! empty( $item['answer'] ) ) {
				$answer_text = $item['answer'];
				
				// Process answer for rich content
				$answer = array(
					'@type' => 'Answer',
					'text' => wp_strip_all_tags( $answer_text ),
				);
				
				// If answer contains HTML, also provide as HTML
				if ( $answer_text !== wp_strip_all_tags( $answer_text ) ) {
					$answer['text'] = array(
						'@type' => 'TextObject',
						'text' => wp_strip_all_tags( $answer_text ),
						'encodingFormat' => 'text/html',
						'text' => $answer_text,
					);
				}
				
				// Add answer author if specified
				$answer_author = ! empty( $item['author'] ) ? $item['author'] : null;
				if ( $answer_author ) {
					$answer['author'] = array(
						'@type' => 'Person',
						'name' => $answer_author,
					);
				} else {
					$answer['author'] = $this->get_author_properties( $post->post_author );
				}
				
				// Add date created
				$date_created = ! empty( $item['dateCreated'] ) ? $item['dateCreated'] : get_the_date( 'c', $post );
				$answer['dateCreated'] = $date_created;
				
				// Add upvote count if available
				if ( ! empty( $item['upvoteCount'] ) ) {
					$answer['upvoteCount'] = intval( $item['upvoteCount'] );
				}
				
				$question['acceptedAnswer'] = $answer;
			} else {
				continue; // Skip if no answer
			}
			
			// Add answer count (always 1 for accepted answer)
			$question['answerCount'] = 1;
			
			// Add date created for question
			$question['dateCreated'] = ! empty( $item['dateCreated'] ) ? $item['dateCreated'] : get_the_date( 'c', $post );
			
			// Add position
			$question['position'] = $index + 1;
			
			// Add question ID
			$question['@id'] = get_permalink( $post ) . '#question-' . ( $index + 1 );
			
			// Add keywords for the specific question
			if ( ! empty( $item['keywords'] ) ) {
				$question['keywords'] = $item['keywords'];
			}
			
			$questions[] = $question;
		}
		
		return $questions;
	}
	
	/**
	 * Extract FAQ from content
	 */
	private function extract_faq_from_content( $content ) {
		$faq_items = array();
		
		// Try to find FAQ structured with headings and paragraphs
		// Pattern 1: H2/H3 as questions, following content as answer
		preg_match_all( '/<h[23][^>]*>(.*?)<\/h[23]>(.*?)(?=<h[23]|$)/is', $content, $matches );
		
		if ( ! empty( $matches[1] ) && ! empty( $matches[2] ) ) {
			foreach ( $matches[1] as $index => $question ) {
				$answer = $matches[2][$index];
				
				// Clean up the answer
				$answer = trim( $answer );
				$answer = preg_replace( '/<\/?(div|section)[^>]*>/i', '', $answer );
				
				if ( ! empty( $question ) && ! empty( $answer ) ) {
					$faq_items[] = array(
						'question' => wp_strip_all_tags( $question ),
						'answer' => trim( $answer ),
					);
				}
			}
		}
		
		// Pattern 2: FAQ list items
		if ( empty( $faq_items ) ) {
			preg_match_all( '/<li[^>]*class="[^"]*faq-item[^"]*"[^>]*>(.*?)<\/li>/is', $content, $list_matches );
			
			if ( ! empty( $list_matches[1] ) ) {
				foreach ( $list_matches[1] as $item ) {
					// Try to extract question and answer from list item
					preg_match( '/<(?:strong|b|span[^>]*class="[^"]*question[^"]*")[^>]*>(.*?)<\/(?:strong|b|span)>(.*)$/is', $item, $qa_match );
					
					if ( ! empty( $qa_match[1] ) && ! empty( $qa_match[2] ) ) {
						$faq_items[] = array(
							'question' => wp_strip_all_tags( $qa_match[1] ),
							'answer' => trim( $qa_match[2] ),
						);
					}
				}
			}
		}
		
		// Pattern 3: Definition list
		if ( empty( $faq_items ) ) {
			preg_match_all( '/<dt[^>]*>(.*?)<\/dt>\s*<dd[^>]*>(.*?)<\/dd>/is', $content, $dl_matches );
			
			if ( ! empty( $dl_matches[1] ) && ! empty( $dl_matches[2] ) ) {
				foreach ( $dl_matches[1] as $index => $question ) {
					$answer = $dl_matches[2][$index];
					
					if ( ! empty( $question ) && ! empty( $answer ) ) {
						$faq_items[] = array(
							'question' => wp_strip_all_tags( $question ),
							'answer' => trim( $answer ),
						);
					}
				}
			}
		}
		
		// Pattern 4: Accordion or collapsible elements
		if ( empty( $faq_items ) ) {
			preg_match_all( '/<(?:summary|button)[^>]*class="[^"]*(?:accordion|collapsible|faq)[^"]*"[^>]*>(.*?)<\/(?:summary|button)>\s*<(?:div|p|details)[^>]*>(.*?)<\/(?:div|p|details)>/is', $content, $accordion_matches );
			
			if ( ! empty( $accordion_matches[1] ) && ! empty( $accordion_matches[2] ) ) {
				foreach ( $accordion_matches[1] as $index => $question ) {
					$answer = $accordion_matches[2][$index];
					
					if ( ! empty( $question ) && ! empty( $answer ) ) {
						$faq_items[] = array(
							'question' => wp_strip_all_tags( $question ),
							'answer' => trim( $answer ),
						);
					}
				}
			}
		}
		
		return $faq_items;
	}
}