<?php
defined( 'ABSPATH' ) || exit;

/**
 * Coordinates production lifecycle actions for admin requests.
 */
final class Costudio_Admin_Production_Lifecycle {

	private function __construct() {
	}

	/**
	 * Start a production from sanitized admin request data.
	 *
	 * @param array<string,mixed> $request Unslashed admin request data.
	 * @return array<string,mixed>|WP_Error
	 */
	public static function start_production( array $request ) {
		$settings = costudio_settings();
		$ai_mode  = $settings ? $settings->get( 'ai_mode', 'contentos' ) : 'contentos';
		$api_key  = $settings ? $settings->get( 'ai_api_key' ) : '';

		if ( $ai_mode === 'byok' && empty( $api_key ) ) {
			return new WP_Error(
				'byok_missing_api_key',
				__( 'BYOK is selected but no API key is configured. Open Settings → AI Provider, save your key, or switch to ContentOS Auto.', 'contentosapp-studio' )
			);
		}

		if ( $ai_mode === 'contentos' ) {
			Costudio_Standalone_License::sync_remote_usage();
		}

		$language_source = '' !== trim( (string) ( $request['lang_code'] ?? '' ) ) ? 'form' : 'global_fallback';
		$inputs          = self::build_inputs( $request, $ai_mode );
		$site_key       = sanitize_key( $request['site_key'] ?? '' );
		$plan_id        = (int) ( $request['plan_id'] ?? 0 );

		$sites_repo = costudio_sites();
		$site_cfg   = $sites_repo ? $sites_repo->get( $site_key ) : null;
		if ( ! $site_cfg || empty( $site_cfg['active'] ) ) {
			return new WP_Error(
				'inactive_site',
				__( 'This site is inactive (or not configured). Activate it in Contentosapp Studio → Settings → Sites before producing/publishing.', 'contentosapp-studio' )
			);
		}
		$validation_error = Costudio_Admin_Production_Validator::validate_inputs( $inputs );
		if ( $validation_error ) {
			return new WP_Error( 'invalid_production_inputs', $validation_error );
		}

		$warning = Costudio_Admin_Production_Validator::check_keyword_duplicate( $site_key, $inputs['keyword'] );

		$production_id = Costudio_Production::create(
			array(
				'site_key' => $site_key,
				'keyword'  => $inputs['keyword'],
				'title'    => $inputs['angulo'],
				'plan_id'  => $plan_id,
				'inputs'   => $inputs,
			)
		);

		if ( function_exists( 'costudio_log' ) ) {
			costudio_log(
				'production.language_snapshotted',
				array(
					'production_id' => $production_id,
					'lang_code'     => $inputs['lang_code'],
					'source'        => $language_source,
				)
			);
		}

		if ( $plan_id ) {
			Costudio_Planning::update_status( $plan_id, 'producing' );
		}

		self::seed_links( $production_id, $site_key, $inputs, $request );
		$queue = self::dispatch_pipeline( $production_id );

		return array(
			'production_id' => $production_id,
			'warning'       => $warning,
			'async'         => true,
			'queue'         => $queue,
		);
	}

	/**
	 * @param array<string,mixed> $request
	 * @return array<string,mixed>
	 */
	private static function build_inputs( array $request, string $ai_mode ): array {
		$publish_mode = sanitize_key( $request['publish_mode'] ?? 'draft' );
		if ( ! in_array( $publish_mode, array( 'draft', 'scheduled', 'published' ), true ) ) {
			$publish_mode = 'draft';
		}

		$execution_mode = sanitize_key( $request['execution_mode'] ?? 'auto' );
		if ( ! in_array( $execution_mode, array( 'auto', 'manual' ), true ) ) {
			$execution_mode = 'auto';
		}

		$lang_code = trim( sanitize_text_field( $request['lang_code'] ?? '' ) );
		if ( '' === $lang_code ) {
			$lang_code = Costudio_Admin::get_default_content_language();
		}

		$inputs = array(
			'nicho'          => sanitize_text_field( $request['nicho']        ?? '' ),
			'categoria'      => sanitize_text_field( $request['categoria']    ?? '' ),
			'keyword'        => sanitize_text_field( $request['keyword']      ?? '' ),
			'angulo'         => sanitize_text_field( $request['angulo']       ?? '' ),
			'perfil'         => sanitize_text_field( $request['perfil']       ?? '' ),
			'article_type'   => Costudio_Article_Types::normalize( sanitize_key( $request['article_type'] ?? '' ) ),
			'extensao'       => sanitize_text_field( $request['extensao']     ?? '2000-2600' ),
			'observacoes'    => sanitize_textarea_field( $request['observacoes'] ?? '' ),
			'publish_mode'   => $publish_mode,
			'publish_date'   => sanitize_text_field( $request['publish_date'] ?? '' ),
			'execution_mode' => $execution_mode,
			'ai_mode'        => $ai_mode,
			'lang_code'      => $lang_code,
			'lang_name'      => Costudio_Admin::get_content_language_name( $lang_code ),
		);

		$inputs['pilar_url']   = esc_url_raw( $request['pilar_url'] ?? '' );
		$inputs['pilar_title'] = sanitize_text_field( $request['pilar_title'] ?? '' );

		$comparison_items              = $request['comparison_items'] ?? array();
		$inputs['comparison_criteria'] = sanitize_text_field( $request['comparison_criteria'] ?? '' );
		$inputs['comparison_items']    = array_map(
			static function ( $item ) {
				$item = is_array( $item ) ? $item : array();
				return array(
					'label' => sanitize_text_field( $item['label'] ?? '' ),
					'url'   => esc_url_raw( $item['url'] ?? '' ),
				);
			},
			(array) $comparison_items
		);

		$news_sources           = $request['news_sources'] ?? array();
		$inputs['news_sources'] = array_map(
			static function ( $source ) {
				$source = is_array( $source ) ? $source : array();
				return array( 'url' => esc_url_raw( $source['url'] ?? '' ) );
			},
			(array) $news_sources
		);

		// Author of the news article — resolved against WP users. Stored as ID;
		// the input-mapper resolves name/URL at prompt-build time so any later
		// rename of the WP user reflects without re-saving production inputs.
		$inputs['news_author_id'] = (int) ( $request['news_author_id'] ?? 0 );

		$inputs['update_post_id']      = intval( $request['update_post_id'] ?? 0 );
		$inputs['update_post_url']     = esc_url_raw( $request['update_post_url'] ?? '' );
		$inputs['update_post_title']   = sanitize_text_field( $request['update_post_title'] ?? '' );
		$inputs['update_post_content'] = self::sanitize_block_markup_string( (string) ( $request['update_post_content'] ?? '' ) );
		$inputs['update_instructions'] = sanitize_textarea_field( $request['update_instructions'] ?? '' );
		$inputs['notas_adicionais']    = sanitize_textarea_field( $request['notas_adicionais'] ?? '' );

		// Snapshot image settings at creation time so the pipeline behaves
		// consistently regardless of settings changes during async execution.
		$cts_snap = function_exists( 'costudio_settings' ) ? costudio_settings() : null;
		if ( $cts_snap ) {
			$snap_mode = (string) $cts_snap->get( 'costudio_image_mode', 'generate' );
			$inputs['costudio_image_mode']     = in_array( $snap_mode, array( 'generate', 'placeholder', 'none' ), true ) ? $snap_mode : 'generate';
			$inputs['costudio_image_quantity'] = class_exists( 'Costudio_Standalone_Settings' )
				? Costudio_Standalone_Settings::clamp_image_quantity( $cts_snap->get( 'costudio_image_quantity', 2 ), $ai_mode )
				: max( 1, min( 3, intval( $cts_snap->get( 'costudio_image_quantity', 2 ) ) ) );
		}

		return $inputs;
	}

	/**
	 * @param array<string,mixed> $inputs
	 * @param array<string,mixed> $request
	 */
	private static function seed_links( int $production_id, string $site_key, array $inputs, array $request ): void {
		try {
			$links_json = self::sanitize_links_json( isset( $request['links_internos'] ) ? (string) $request['links_internos'] : '' );

			if ( ! empty( $links_json ) && strpos( $links_json, '{' ) === 0 ) {
				Costudio_Production::set_links( $production_id, $links_json );
				return;
			}

			$link_query = $inputs['keyword'] ?? '';
			$kws        = array_filter( array_map( 'trim', explode( ',', $link_query ) ) );
			$finder     = new Costudio_Link_Finder();
			$links      = $finder->find( $kws, array( $site_key ) );

			Costudio_Production::set_links(
				$production_id,
				(string) wp_json_encode(
					array(
						'internal' => $links,
						'external' => array(),
					)
				)
			);
		} catch ( \Throwable $e ) {
			// Non-fatal: production can continue without pre-seeded links.
		}
	}

	private static function sanitize_block_markup_string( string $content, int $max_chars = 40000 ): string {
		$content = wp_check_invalid_utf8( $content, true );
		$content = str_replace( "\0", '', $content );
		$content = preg_replace( '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]/', '', $content );
		$content = is_string( $content ) ? $content : '';

		if ( $max_chars > 0 && mb_strlen( $content ) > $max_chars ) {
			$content = mb_substr( $content, 0, $max_chars );
		}

		return $content;
	}

	private static function sanitize_links_json( string $links_json ): string {
		if ( '' === trim( $links_json ) ) {
			return '';
		}

		$decoded = json_decode( $links_json, true );
		if ( ! is_array( $decoded ) ) {
			return '';
		}

		$clean = array(
			'internal' => self::sanitize_internal_links_payload( $decoded['internal'] ?? array() ),
			'external' => self::sanitize_external_links_payload( $decoded['external'] ?? array() ),
		);
		$encoded = wp_json_encode( $clean );

		return is_string( $encoded ) ? $encoded : '';
	}

	private static function sanitize_internal_links_payload( $items ): array {
		$items = is_array( $items ) ? array_slice( $items, 0, 100 ) : array();
		$clean = array();

		foreach ( $items as $item ) {
			if ( ! is_array( $item ) ) {
				continue;
			}

			$url = esc_url_raw( (string) ( $item['url'] ?? '' ) );
			if ( '' === $url ) {
				continue;
			}

			$post_type = sanitize_key( (string) ( $item['post_type'] ?? 'post' ) );
			$clean[]   = array(
				'title'     => sanitize_text_field( (string) ( $item['title'] ?? '' ) ),
				'url'       => $url,
				'site_key'  => sanitize_key( (string) ( $item['site_key'] ?? '' ) ),
				'site_name' => sanitize_text_field( (string) ( $item['site_name'] ?? '' ) ),
				'post_type' => in_array( $post_type, array( 'post', 'page' ), true ) ? $post_type : 'post',
				'selected'  => true,
			);
		}

		return $clean;
	}

	private static function sanitize_external_links_payload( $items ): array {
		$items = is_array( $items ) ? array_slice( $items, 0, 50 ) : array();
		$clean = array();

		foreach ( $items as $item ) {
			if ( ! is_array( $item ) ) {
				continue;
			}

			$url = esc_url_raw( (string) ( $item['url'] ?? '' ) );
			if ( '' === $url ) {
				continue;
			}

			$clean[] = array(
				'url'         => $url,
				'description' => sanitize_textarea_field( (string) ( $item['description'] ?? '' ) ),
			);
		}

		return $clean;
	}

	private static function dispatch_pipeline( int $production_id ): array {
		if ( class_exists( 'Costudio_Production_Queue' ) ) {
			return Costudio_Production_Queue::submit( $production_id );
		}

		Costudio_Production::mark_pipeline_started( $production_id );
		Costudio_Runner::pipeline_log_append(
			$production_id,
			__( 'Pedido recebido. A iniciar o processamento em segundo plano.', 'contentosapp-studio' ),
			'info'
		);

		$secret_token = wp_generate_password( 32, false );
		Costudio_Runner::prime_background_token( $production_id, $secret_token, 'ajax_start_production' );
		Costudio_Runner::kick_off_background( $production_id, $secret_token );

		return array(
			'queued'   => false,
			'status'   => 'running',
			'position' => 0,
		);
	}
}
