<?php
namespace KBT_SEO;

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

/**
 * Auto-generate FAQ Schema (JSON-LD) from post content.
 *
 * Detects FAQ patterns in articles:
 * 1. Gutenberg FAQ blocks (wp:yoast/faq-block, rank-math faq block)
 * 2. Manual H2/H3 headings that look like questions (end with ?)
 * 3. <strong>Q:</strong> / <strong>A:</strong> patterns
 * 4. <dt>/<dd> definition lists
 *
 * The schema is automatically injected into <head> on single posts.
 */
class FAQ_Schema {

	public static function init() {
		add_action( 'wp_head', array( __CLASS__, 'output_schema' ), 10 );
		add_action( 'add_meta_boxes', array( __CLASS__, 'register_meta_box' ) );
		add_action( 'save_post', array( __CLASS__, 'save_meta' ), 10, 2 );
	}

	/**
	 * Output FAQ schema JSON-LD in <head>.
	 */
	public static function output_schema() {
		if ( ! is_singular( 'post' ) ) return;

		global $post;
		$faqs = self::extract_faqs( $post );

		if ( empty( $faqs ) ) return;

		$schema = array(
			'@context'   => 'https://schema.org',
			'@type'      => 'FAQPage',
			'mainEntity' => array(),
		);

		foreach ( $faqs as $faq ) {
			$schema['mainEntity'][] = array(
				'@type'          => 'Question',
				'name'           => $faq['question'],
				'acceptedAnswer' => array(
					'@type' => 'Answer',
					'text'  => $faq['answer'],
				),
			);
		}

		echo '<script type="application/ld+json">' . wp_json_encode( $schema, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE ) . '</script>' . "\n";
	}

	/**
	 * Extract FAQ pairs from post content using multiple detection methods.
	 *
	 * @param \WP_Post $post
	 * @return array [['question'=>'...', 'answer'=>'...'], ...]
	 */
	public static function extract_faqs( $post ) {
		$content = $post->post_content;
		$faqs    = array();

		// Check for manually entered FAQs first (meta box)
		$manual = get_post_meta( $post->ID, '_kbt_faq_manual', true );
		if ( ! empty( $manual ) && is_array( $manual ) ) {
			foreach ( $manual as $m ) {
				if ( ! empty( $m['q'] ) && ! empty( $m['a'] ) ) {
					$faqs[] = array(
						'question' => wp_strip_all_tags( $m['q'] ),
						'answer'   => wp_strip_all_tags( $m['a'] ),
					);
				}
			}
			if ( ! empty( $faqs ) ) return $faqs;
		}

		// Method 1: Headings that are questions (H2/H3 ending with ?)
		// Collect heading + next content until next heading
		$faqs = self::extract_from_question_headings( $content );
		if ( ! empty( $faqs ) ) return $faqs;

		// Method 2: Q&A bold pattern  (Q: ... A: ...)
		$faqs = self::extract_from_qa_pattern( $content );
		if ( ! empty( $faqs ) ) return $faqs;

		// Method 3: Definition list <dl><dt><dd>
		$faqs = self::extract_from_dl( $content );
		if ( ! empty( $faqs ) ) return $faqs;

		return $faqs;
	}

	/**
	 * Extract FAQs from headings that end with "?"
	 */
	private static function extract_from_question_headings( $content ) {
		$faqs = array();

		// Split content by headings
		$parts = preg_split( '/(<h[2-3][^>]*>.*?<\/h[2-3]>)/is', $content, -1, PREG_SPLIT_DELIM_CAPTURE );

		for ( $i = 0; $i < count( $parts ); $i++ ) {
			// Check if this part is a heading
			if ( preg_match( '/<h[2-3][^>]*>(.*?)<\/h[2-3]>/is', $parts[ $i ], $hm ) ) {
				$question = trim( wp_strip_all_tags( $hm[1] ) );

				// Check if it's a question (ends with ?)
				if ( substr( $question, -1 ) === '?' ) {
					// Get the content after this heading (next part)
					$answer = '';
					if ( isset( $parts[ $i + 1 ] ) ) {
						$answer = trim( wp_strip_all_tags( $parts[ $i + 1 ] ) );
					}

					if ( ! empty( $answer ) && mb_strlen( $answer ) > 20 ) {
						// Limit answer to ~300 chars for schema
						if ( mb_strlen( $answer ) > 300 ) {
							$answer = mb_substr( $answer, 0, 297 ) . '...';
						}
						$faqs[] = array(
							'question' => $question,
							'answer'   => $answer,
						);
					}
				}
			}
		}

		return $faqs;
	}

	/**
	 * Extract FAQs from Q:/A: bold patterns.
	 */
	private static function extract_from_qa_pattern( $content ) {
		$faqs = array();

		// Pattern: <strong>Q:</strong> question text followed by <strong>A:</strong> answer text
		if ( preg_match_all(
			'/<(?:strong|b)>\s*(?:Q|Pertanyaan|Tanya)\s*[:\.]?\s*<\/(?:strong|b)>\s*(.*?)(?=<(?:strong|b)>\s*(?:A|Jawab|Jawaban)\s*[:\.]?\s*<\/(?:strong|b)>)/is',
			$content, $questions
		) && preg_match_all(
			'/<(?:strong|b)>\s*(?:A|Jawab|Jawaban)\s*[:\.]?\s*<\/(?:strong|b)>\s*(.*?)(?=<(?:strong|b)>\s*(?:Q|Pertanyaan|Tanya)|$)/is',
			$content, $answers
		) ) {
			$count = min( count( $questions[1] ), count( $answers[1] ) );
			for ( $i = 0; $i < $count; $i++ ) {
				$q = trim( wp_strip_all_tags( $questions[1][ $i ] ) );
				$a = trim( wp_strip_all_tags( $answers[1][ $i ] ) );
				if ( ! empty( $q ) && ! empty( $a ) ) {
					if ( mb_strlen( $a ) > 300 ) $a = mb_substr( $a, 0, 297 ) . '...';
					$faqs[] = array( 'question' => $q, 'answer' => $a );
				}
			}
		}

		return $faqs;
	}

	/**
	 * Extract FAQs from <dl> definition lists.
	 */
	private static function extract_from_dl( $content ) {
		$faqs = array();

		if ( preg_match_all( '/<dt[^>]*>(.*?)<\/dt>\s*<dd[^>]*>(.*?)<\/dd>/is', $content, $dl ) ) {
			for ( $i = 0; $i < count( $dl[1] ); $i++ ) {
				$q = trim( wp_strip_all_tags( $dl[1][ $i ] ) );
				$a = trim( wp_strip_all_tags( $dl[2][ $i ] ) );
				if ( ! empty( $q ) && ! empty( $a ) ) {
					if ( mb_strlen( $a ) > 300 ) $a = mb_substr( $a, 0, 297 ) . '...';
					$faqs[] = array( 'question' => $q, 'answer' => $a );
				}
			}
		}

		return $faqs;
	}

	/**
	 * Register meta box for manual FAQ entry.
	 */
	public static function register_meta_box() {
		add_meta_box(
			'kbt-faq-schema',
			'FAQ Schema',
			array( __CLASS__, 'render_meta_box' ),
			'post',
			'normal',
			'low'
		);
	}

	/**
	 * Render FAQ meta box.
	 */
	public static function render_meta_box( $post ) {
		$faqs = get_post_meta( $post->ID, '_kbt_faq_manual', true );
		if ( ! is_array( $faqs ) ) $faqs = array();

		wp_nonce_field( 'kbt_faq_save', 'kbt_faq_nonce' );
		?>
		<p style="color:#666;font-size:13px;margin-top:0;">
			FAQ schema akan <strong>auto-detect</strong> dari heading yang berakhiran "?" di konten artikel.
			Atau masukkan FAQ manual di bawah ini:
		</p>
		<div id="kbt-faq-entries">
			<?php
			if ( ! empty( $faqs ) ) {
				foreach ( $faqs as $i => $faq ) {
					self::render_faq_row( $i, $faq['q'] ?? '', $faq['a'] ?? '' );
				}
			}
			?>
		</div>
		<button type="button" class="button" onclick="kbtAddFaq()">+ Tambah FAQ</button>

		<script>
		var kbtFaqIdx = <?php echo max( 0, count( $faqs ) ); ?>;
		function kbtAddFaq() {
			var html = '<div class="kbt-faq-row" style="background:#f9f9f9;padding:12px;margin:8px 0;border-radius:6px;border:1px solid #ddd;">';
			html += '<p style="margin:0 0 8px;"><label><strong>Pertanyaan:</strong></label><br>';
			html += '<input type="text" name="kbt_faq[' + kbtFaqIdx + '][q]" style="width:100%;padding:6px;" placeholder="Tulis pertanyaan..." /></p>';
			html += '<p style="margin:0;"><label><strong>Jawaban:</strong></label><br>';
			html += '<textarea name="kbt_faq[' + kbtFaqIdx + '][a]" rows="3" style="width:100%;padding:6px;" placeholder="Tulis jawaban..."></textarea></p>';
			html += '<button type="button" class="button-link" style="color:#b32d2e;margin-top:6px;" onclick="this.closest(\'.kbt-faq-row\').remove()">Hapus</button>';
			html += '</div>';
			document.getElementById('kbt-faq-entries').insertAdjacentHTML('beforeend', html);
			kbtFaqIdx++;
		}
		</script>
		<?php
	}

	private static function render_faq_row( $idx, $q, $a ) {
		?>
		<div class="kbt-faq-row" style="background:#f9f9f9;padding:12px;margin:8px 0;border-radius:6px;border:1px solid #ddd;">
			<p style="margin:0 0 8px;">
				<label><strong>Pertanyaan:</strong></label><br>
				<input type="text" name="kbt_faq[<?php echo $idx; ?>][q]" value="<?php echo esc_attr( $q ); ?>"
					   style="width:100%;padding:6px;" placeholder="Tulis pertanyaan..." />
			</p>
			<p style="margin:0;">
				<label><strong>Jawaban:</strong></label><br>
				<textarea name="kbt_faq[<?php echo $idx; ?>][a]" rows="3"
						  style="width:100%;padding:6px;" placeholder="Tulis jawaban..."><?php echo esc_textarea( $a ); ?></textarea>
			</p>
			<button type="button" class="button-link" style="color:#b32d2e;margin-top:6px;"
					onclick="this.closest('.kbt-faq-row').remove()">Hapus</button>
		</div>
		<?php
	}

	/**
	 * Save manual FAQ entries.
	 */
	public static function save_meta( $post_id, $post ) {
		if ( ! isset( $_POST['kbt_faq_nonce'] ) || ! wp_verify_nonce( $_POST['kbt_faq_nonce'], 'kbt_faq_save' ) ) return;
		if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
		if ( ! current_user_can( 'edit_post', $post_id ) ) return;

		if ( isset( $_POST['kbt_faq'] ) && is_array( $_POST['kbt_faq'] ) ) {
			$clean = array();
			foreach ( $_POST['kbt_faq'] as $faq ) {
				$q = sanitize_text_field( $faq['q'] ?? '' );
				$a = sanitize_textarea_field( $faq['a'] ?? '' );
				if ( ! empty( $q ) && ! empty( $a ) ) {
					$clean[] = array( 'q' => $q, 'a' => $a );
				}
			}
			update_post_meta( $post_id, '_kbt_faq_manual', $clean );
		} else {
			delete_post_meta( $post_id, '_kbt_faq_manual' );
		}
	}
}
