<?php if (!defined('ABSPATH'))
	exit; ?>
<?php

class polylai_Ajax
{
	var $translator;

	public function __construct()
	{
		$this->translator = new polylai_Translator();
	}
	
	/**
	 * Count posts based on post type, source language and translation status
	 */
	public function count_posts()
	{
		// Verify nonce for security
		if (!isset($_POST['nonce']) || !wp_verify_nonce($_POST['nonce'], 'polylai_settings_nonce')) {
			wp_send_json_error(['message' => 'Invalid security token.']);
			exit;
		}
		
		// Get parameters
		$post_type = isset($_POST['post_type']) ? sanitize_text_field($_POST['post_type']) : '';
		$translate_from = isset($_POST['translate_from']) ? sanitize_text_field($_POST['translate_from']) : '';
		$only_missing = isset($_POST['only_missing']) ? (bool)$_POST['only_missing'] : false;
		$categories = isset($_POST['categories']) ? sanitize_text_field($_POST['categories']) : '';
		$category_array = ! empty( $categories ) ? array_map( 'intval', explode( ',', $categories ) ) : [];
		
		if (empty($post_type)) {
			wp_send_json_error(['message' => 'Post type is required.']);
			exit;
		}
		
		if (empty($translate_from)) {
			wp_send_json_error(['message' => 'Source language is required.']);
			exit;
		}
		
		// Make sure post type exists and is valid
		$post_types = get_post_types(['public' => true]);
		if (!in_array($post_type, $post_types)) {
			wp_send_json_error(['message' => 'Invalid post type.']);
			exit;
		}
				
		// Get languages from Polylang
		$languages = [];
		if (function_exists('pll_languages_list')) {
			$languages = pll_languages_list();
		}
		
		if (empty($languages)) {
			wp_send_json_error(['message' => 'No languages found.']);
			exit;
		}
		
		// Query parameters for posts in the selected source language
		$args = [
			'post_type'      => $post_type,
			'posts_per_page' => -1, // Get all posts
			'post_status'    => 'publish',
			'fields'         => 'ids', // Only get post IDs for efficiency
			'lang'           => $translate_from, // Filter by source language
			'category__in'   => $category_array, // Filter by selected categories
		];
		
		// If only missing translations requested, we'll filter the results
		$post_count = 0;
		$posts = get_posts($args);
		
		$post_count = count($posts);
		
		wp_send_json_success(['count' => $post_count]);
		exit;
	}

	public function check_cloud()
	{
		if (isset($_GET['cloud']) && $_GET['cloud'] == '1') {
			$this->update_cloud_status();
		}
	}

	public function trigger()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}		
		try {
			$this->update_cloud_status();
			$has_cron = get_transient(polylai_Cron::LOCK_TRANSIENT_KEY);

			if (!$has_cron && polylai_Cron::getInstance()->check_for_posts()) {
				polylai_Utils::db_log('debug', 'progress', "launching cron");
				$exec_url = home_url('/index.php?action=polylai_run_cron');
				wp_remote_post($exec_url, [
					'timeout' => 0.01,
					'blocking' => false,
					'headers' => [
						'Connection' => 'Close',
						'Contect-length' => 0
					]
				]);
			} else {
				polylai_Utils::db_log('debug', 'progress', "no posts to translate");
			}
		} catch (Exception $e) {
			polylai_Utils::db_log('error', 'trigger', $e->getMessage());
			wp_send_json_error(['message' => $e->getMessage()]);
			wp_die();
		}
	}

	public function update_cloud_status()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}

		$license = get_option('polylai_credits_license');
		if (!$license) {
			return;
		}
		$running = get_transient(POLYLAI_CLOUD_TRANSIENT);
		if ($running) {
			polylai_Utils::db_log(
				'debug',
				'update_cloud_status',
				"already running"
			);
			return;
		}
		set_transient(POLYLAI_CLOUD_TRANSIENT, '1', 2);

		/// TODO only fetch cloud pending
		$results = polylai_Manager::getInstance()->list_pending_translating();

		$guids = [];
		foreach ($results as $item) {
			if ($item->cloud_guid) {
				$guids[] = $item->cloud_guid;
			}
		}

		if (count($guids) == 0) {
			return;
		}

		polylai_Utils::db_log(
			'debug',
			'update_cloud_status',
			"found " . count($results) . " to update"
		);

		$statusRequest = new polylai_CloudStatus();
		$statusRequest->license_key = get_option('polylai_credits_license');
		$statusRequest->guids = $guids;

		$status = polylai_Cloud::getStatus($statusRequest);

		polylai_Utils::db_log(
			'debug',
			'update_cloud_status',
			"get status",
			null,
			null,
			json_encode($status)
		);

		foreach ($status as $item) {
			$postTranslation = polylai_Manager::getInstance()->get_from_list($results, $item->guid);

			$post_id = $item->post_id;

			polylai_Utils::db_log(
				'debug',
				'update_cloud_status',
				"get post id",
				$post_id,
				null,
				$item->used_tokens
			);


			polylai_Manager::getInstance()->set_status(
				$postTranslation->id,
				$item->status,
				$item->error_code,
				$item->used_tokens,
				$item->translations
			);
			if ($item->status == "complete") {
				$post_title = "";
				$post_content = "";
				$post_excerpt = "";
				$meta = [];

				foreach ($item->translations as $translation) {
					if ($translation->field == "post_title") {
						$post_title = $translation->translated_text;
					}
					if ($translation->field == "post_content") {
						$post_content = $translation->translated_text;
					}
					if ($translation->field == "post_excerpt") {
						$post_excerpt = $translation->translated_text;
					}
					if ($translation->field == "meta") {
						$meta_key = $translation->meta_key;
						$meta[$meta_key] = $translation->translated_text;
					}
				}

				$meta = array_merge($meta, polylai_ACF::copy_meta($post_id));

				polylai_Utils::db_log(
					'debug',
					'update_cloud_status',
					"pre create translation",
					$post_id,
					$post_title
				);

				$duplicator = new polylai_Duplicator();
				$new_post_id = $duplicator->duplicate($post_id, $post_title, $post_content, $post_excerpt, $postTranslation->final_post_status, $meta);

				$this->translator->create_translation(
					$post_id,
					$new_post_id,
					$item->locale_to,
					$meta
				);

				try {
					polylai_Manager::getInstance()->set_completed($postTranslation->id);
				} catch (\Exception $e) {
					polylai_Utils::db_log('debug', 'ajax -> error', $e->getMessage());
				}
			}
		}
	}

	private function enqueue_single_translation($id, $locales, $langs, $post_status, $date, $service)
	{
		$post = get_post($id);
		$post_lang = pll_get_post_language($id, 'name');

		$index = 0;
		$locales_arr = explode(",", $locales);
		$source_post_id = $id;

		$errors = [];
		foreach (explode(",", $langs) as $lang) {
			$data = null;
			$locale_to = $locales_arr[$index];

			$post_data = new polylai_Data();
			// $post_data->date = $date;
			$post_data->lang_from = $post_lang;
			$post_data->lang_to = $lang;
			$post_data->service = $service;
			$post_data->final_post_status = $post_status;
			$post_data->locale_to = $locale_to;
			$post_data->source_post_id = $source_post_id;
			$post_data->used_tokens = 0;

			$requestError = null;
			if ($service == 'cloud') {
				$license_key = get_option('polylai_credits_license');

				$cloudRequest = new polylai_CloudRequest($post_lang, $lang, $locale_to, $post, $license_key);
				$post_data->request_id = $cloudRequest->request_id;

				// Add meta values to the cloud request
				$meta_keys = [
					'_elementor_data',
					'_yoast_wpseo_bctitle',
					'_yoast_wpseo_metadesc',
					'_yoast_wpseo_focuskw',
					'_yoast_wpseo_title',
					'rank_math_title',
					'rank_math_description',
					'rank_math_facebook_title',
					'rank_math_facebook_description',
					'rank_math_twitter_use_facebook',
					'rank_math_twitter_title',
					'rank_math_twitter_description',
					'rank_math_focus_keyword',
					'_purchase_note',
					'_product_attributes',
					'_downloadable_files'
				];

				foreach ($meta_keys as $meta_key) {
					$meta_value = get_post_meta($id, $meta_key, true);
					if (!empty($meta_value)) {
						$cloudRequest->meta[$meta_key] = $meta_value;
					}
				}

				$response = polylai_Cloud::requestTranslation($cloudRequest);

				if ($response->success) {
					$post_data->cloud_guid = $response->meta->guid;
					$id = polylai_Manager::getInstance()->add($post->post_title, $post->ID, $post_data);
				} else {
					polylai_Utils::db_log('error', 'enqueue', "Unable to request translation", $id, $post->post_title, json_encode($response));
					$errors[] = [
						'request' => $cloudRequest,
						'post' => [
							'ID' => $post->ID,
							'title' => $post->post_title,
							'data' => $post_data
						]
					];
				}

				$data = $cloudRequest;
			} else {
				$id = polylai_Manager::getInstance()->add($post->post_title, $post->ID, $post_data);
				if ($requestError) {
					polylai_Manager::getInstance()->set_status($id, 'error', $requestError);
				}
			}

			$index++;
		}
	}

	public function enqueue_translations()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}

		$id = intval($_POST['id']);
		$locales = sanitize_text_field($_POST['locales']);
		$langs = sanitize_text_field($_POST['localesNames']);
		$post_status = sanitize_text_field($_POST['status']);
		// $date = sanitize_text_field($_POST['date']);

		$service = $_POST['service'];

		$this->enqueue_single_translation($id, $locales, $langs, $post_status, null, $service);

		wp_send_json_success();
		exit;

	}

	public function enqueue_bulk()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}

		$post_type      = isset($_POST['post_type']) ? sanitize_text_field($_POST['post_type']) : '';
		$translate_from = isset($_POST['translate_from']) ? sanitize_text_field($_POST['translate_from']) : '';
		$locales        = isset($_POST['locales']) ? sanitize_text_field($_POST['locales']) : '';
		$langs          = isset($_POST['localesNames']) ? sanitize_text_field($_POST['localesNames']) : '';
		$service        = isset($_POST['service']) ? sanitize_text_field(wp_unslash($_POST['service'])) : '';
		$post_status 	= isset($_POST['post_status']) ? sanitize_text_field(wp_unslash($_POST['post_status'])) : '';
		$categories     = isset($_POST['categories'])    ? sanitize_text_field($_POST['categories']) : '';
		$category_array = ! empty($categories)           ? array_map('intval', explode(',', $categories)) : [];
		$args = [
			'post_type'      => $post_type,
			'posts_per_page' => -1,
			'post_status'    => 'publish',
			'fields'         => 'ids',
			'lang'           => $translate_from,
			'category__in'   => $category_array,
		];

		$post_ids = get_posts($args);

		foreach ($post_ids as $post_id) {
			error_log("enqueue bulk " . $post_id);
			$this->enqueue_single_translation($post_id, $locales, $langs, $post_status, null, $service);
		}

		wp_send_json_success(['count' => count($post_ids)]);
		wp_die();
	}

	public function add_translation()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}
		$data = json_decode(stripslashes($_POST['data']));
		$id = intval($_POST['ID']);
		$title = $_POST['title'];

		polylai_Manager::getInstance()->add($title, $id, $data);
		wp_die();
	}

	public function list_history()
	{
		if (wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['polylai_nonce'])), 'polylai_nonce')) {

			// Get pagination parameters
			$page = isset($_REQUEST['page']) ? absint($_REQUEST['page']) : 1;
			$per_page = isset($_REQUEST['per_page']) ? absint($_REQUEST['per_page']) : 10;

			// Ensure valid values
			$page = max(1, $page);
			$per_page = max(5, min(50, $per_page));

			// Get paginated history
			$result = polylai_Manager::getInstance()->list_history($page, $per_page);

			header("Content-type: application/json");
			echo wp_json_encode([
				'status' => 'OK',
				'data' => $result['items'],
				'pagination' => [
					'total_pages' => $result['total_pages'],
					'total_items' => $result['total_items'],
					'current_page' => $result['current_page'],
					'per_page' => $per_page
				]
			]);

			wp_die();

		}
	}

	public function list_pending()
	{
		//$this->triggerCron();
		if (wp_verify_nonce(sanitize_text_field(wp_unslash($_REQUEST['polylai_nonce'])), 'polylai_nonce')) {

			// get all posts of type translation-polilay
			$list = polylai_Manager::getInstance()->list_pending_translating();

			header("Content-type: application/json");
			echo wp_json_encode([
				'status' => 'OK',
				'data' => $list
			]);

			wp_die();

		}
	}

	/**
	 * Stop all pending and in-progress translations
	 */
	public function stop_all_translations()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}

		try {
			delete_transient(polylai_Cron::LOCK_TRANSIENT_KEY);
			delete_transient(polylai_Cron::REAL_CRON_TRANSIENT_KEY);

			// Get all pending or translating items
			$translations = polylai_Manager::getInstance()->list_pending_translating();
			$count = count($translations);

			// Delete each translation post
			foreach ($translations as $translation) {
				polylai_Manager::getInstance()->set_status($translation->id, 'error', 'cancelled_by_user', 0);
			}

			// Log the action
			polylai_Utils::db_log('info', 'stop_all_translations', "Stopped {$count} translations by user request");

			wp_send_json_success(['message' => sprintf(_n('%d translation stopped', '%d translations stopped', $count, 'ai-translator-for-polylang'), $count), 'count' => $count]);
		} catch (Exception $e) {
			polylai_Utils::db_log('error', 'stop_all_translations', $e->getMessage());
			wp_send_json_error(['message' => $e->getMessage()]);
		}

		wp_die();
	}

	public function get_post_tr_status()
	{
		if (!isset($_POST['polylai_nonce']) || !wp_verify_nonce(sanitize_text_field(wp_unslash($_POST['polylai_nonce'])), 'polylai_nonce')) {
			wp_send_json_error(['message' => 'Invalid nonce']);
			wp_die();
		}

		// nonce not needed here as it's a read-only action
		$id = intval($_POST['id']);

		//  [[it] => (id) [en] => (id)]
		$pll_translations = pll_get_post_translations($id);

		$translations = [];
		$completed = [];

		foreach ($pll_translations as $lang => $translation) {
			$post = get_post($translation);
			if ($post->post_status != 'trash') {
				$completed[] = $lang;
			}
		}

		$pendingTranslating = array_filter(
			polylai_Manager::getInstance()->list_pending_translating(),
			function ($item) use ($id) {
				return $item->source_post_id == $id;
			}
		);

		$pendingTranslating = array_map(function ($item) {
			return $item->locale_to;
		}, $pendingTranslating);

		// take only values of $pendingTranslating
		$pendingTranslating = array_values($pendingTranslating);

		$allowed = polylai_Utils::allowed_langs();
		$has_cron = get_transient(polylai_Cron::REAL_CRON_TRANSIENT_KEY);

		header('Content-type: application/json');
		echo wp_json_encode([
			'post_slug' => pll_get_post_language($id, 'slug'),
			'post_lang' => pll_get_post_language($id, 'name'),
			'translations' => $translations,
			'langs' => pll_languages_list(['fields' => 'name']),
			'langs_slug' => pll_languages_list(['fields' => 'slug']),
			'locales' => pll_the_languages(['raw' => 1, 'hide_if_empty' => 0]),
			'completed' => $completed,
			'allowed' => $allowed,
			'has_cron' => !!$has_cron,
			'has_key' => !!polylai_Utils::has_api_key(),
			'pending_translating' => $pendingTranslating,
			'nonce' => wp_create_nonce('polylai_run_cron')
		]);

		wp_die();
	}
}
