<?php
/**
 * Costudio_Admin_Brand_Voice — AJAX Handlers for Brand Voice.
 *
 * @package Contentosapp_Studio
 * @since   3.2.0
 */

defined( 'ABSPATH' ) || exit;

class Costudio_Admin_Brand_Voice {

	/**
	 * Register AJAX hooks.
	 */
	public static function register_hooks(): void {
		add_action( 'wp_ajax_costudio_get_brand_voice', [ __CLASS__, 'ajax_get' ] );
		add_action( 'wp_ajax_costudio_save_brand_voice', [ __CLASS__, 'ajax_save' ] );
		add_action( 'wp_ajax_costudio_delete_brand_voice', [ __CLASS__, 'ajax_delete' ] );
		add_action( 'wp_ajax_costudio_preview_brand_voice', [ __CLASS__, 'ajax_preview' ] );
	}

	/**
	 * Verify nonce + capability AND read a typed set of request fields in ONE
	 * scope (mirrors Costudio_Admin_Ajax_Base::read_request for this static
	 * controller). The nonce check and every superglobal read live in this
	 * method, so each field is sanitized inline.
	 *
	 * Types: key | text | voice (Brand Voice JSON payload). `source`: 'post'|'get'.
	 *
	 * @param array<string,string> $schema field => type.
	 * @param string               $source 'post' | 'get'.
	 * @return array<string,mixed>
	 */
	private static function read_request( array $schema, string $source = 'post' ): array {
		if ( ! check_ajax_referer( Costudio_Admin::NONCE, 'nonce', false ) ) {
			wp_send_json_error( [ 'message' => __( 'Invalid request.', 'contentosapp-studio' ) ], 403 );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( [ 'message' => __( 'Insufficient permissions.', 'contentosapp-studio' ) ], 403 );
		}

		$is_get = ( 'get' === $source );
		$out    = array();

		foreach ( $schema as $key => $type ) {
			$present = $is_get ? isset( $_GET[ $key ] ) : isset( $_POST[ $key ] );
			if ( ! $present ) {
				$out[ $key ] = ( 'voice' === $type ) ? Costudio_Brand_Voice::sanitize( array() ) : '';
				continue;
			}

			switch ( $type ) {
				case 'voice':
					// Raw JSON payload sanitized as text on read (recognized sanitizer),
					// then decoded and structurally sanitized field-by-field by
					// Costudio_Brand_Voice::sanitize().
					$raw         = $is_get
						? sanitize_textarea_field( wp_unslash( $_GET[ $key ] ) )
						: sanitize_textarea_field( wp_unslash( $_POST[ $key ] ) );
					$out[ $key ] = Costudio_Brand_Voice::sanitize( costudio_decode_json_payload( $raw ) );
					break;
				case 'text':
					$out[ $key ] = $is_get
						? sanitize_text_field( wp_unslash( $_GET[ $key ] ) )
						: sanitize_text_field( wp_unslash( $_POST[ $key ] ) );
					break;
				case 'key':
				default:
					$out[ $key ] = $is_get
						? sanitize_key( wp_unslash( $_GET[ $key ] ) )
						: sanitize_key( wp_unslash( $_POST[ $key ] ) );
					break;
			}
		}

		return $out;
	}

	/**
	 * GET: Retrieve voice for a site.
	 */
	public static function ajax_get(): void {
		$in       = self::read_request( [ 'site_key' => 'key' ], 'get' );
		$voice    = Costudio_Brand_Voice::get( $in['site_key'] );

		wp_send_json_success( [ 'voice' => $voice ] );
	}

	/**
	 * POST: Save voice for a site.
	 */
	public static function ajax_save(): void {
		$in = self::read_request(
			[
				'site_key' => 'key',
				'voice'    => 'voice',
			]
		);

		$site_key = $in['site_key'];
		$voice    = $in['voice'];

		if ( empty( $voice['name'] ) ) {
			wp_send_json_error( [ 'message' => __( 'Voice name is required.', 'contentosapp-studio' ) ] );
		}

		$ok = Costudio_Brand_Voice::save( $site_key, $voice );

		if ( $ok ) {
			wp_send_json_success();
		} else {
			wp_send_json_error( [ 'message' => __( 'Failed to save voice.', 'contentosapp-studio' ) ] );
		}
	}

	/**
	 * POST: Delete voice for a site.
	 */
	public static function ajax_delete(): void {
		$in       = self::read_request( [ 'site_key' => 'key' ] );
		Costudio_Brand_Voice::delete( $in['site_key'] );

		wp_send_json_success();
	}

	/**
	 * POST: Generate a small preview of the voice.
	 */
	public static function ajax_preview(): void {
		$in = self::read_request(
			[
				'site_key' => 'key',
				'voice'    => 'voice',
			]
		);

		$site_key = $in['site_key'];
		$voice    = $in['voice'];

		// Get site niche for context.
		$sites_repo = costudio_sites();
		$sites      = $sites_repo ? $sites_repo->get_all() : [];
		$site_cfg   = $sites[ $site_key ] ?? [];
		$nicho      = ! empty( $site_cfg['niche'] ) ? sanitize_text_field( (string) $site_cfg['niche'] ) : 'o site';

		$lang = Costudio_Admin::get_default_content_language();
		$voice_block = Costudio_Brand_Voice::render_prompt_block( $voice, 4, $lang );

		$prompt = $voice_block . "\n\n"
			. "TAREFA: Escreva um parágrafo de aproximadamente 150 palavras sobre " . $nicho . " "
			. "aplicando RIGOROSAMENTE as diretrizes de voz acima. Não adicione saudações ou comentários.";

		try {
			$pipeline = new Costudio_Pipeline();
			$preview  = $pipeline->generate_ad_hoc( $prompt );
			wp_send_json_success( [ 'preview' => $preview ] );
		} catch ( Throwable $e ) {
			wp_send_json_error( [ 'message' => $e->getMessage() ] );
		}
	}
}
