<?php
/**
 * This file is part of the Wisewand WordPress plugin.
 *
 * @package Wisewand
 * @since 1.0.0
 * @license GPL-2.0-or-later
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program. If not, see <https://www.gnu.org/licenses/>.
 */
namespace Wisewand\WPML;

// Exit if accessed directly
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

use Wisewand\Utils\Options;
use Wisewand\Logging\Logger;

class WPML_Manager {

	private $options;
	private $logger;

	public function __construct( Options $options, Logger $logger ) {
		$this->options = $options;
		$this->logger  = $logger;

		// Hook into post creation to handle WPML integration
		add_action( 'wp_insert_post', array( $this, 'handle_post_language' ), 10, 3 );
		add_action( 'wisewand_process_translation', array( $this, 'process_translation_link' ), 10, 3 );
	}

	public function handle_post_language( $post_id, $post, $update ) {
		// Only process posts with Wisewand external ID
		$external_id = get_post_meta( $post_id, '_wisewand_external_id', true );
		if ( empty( $external_id ) ) {
			return;
		}

		// Get language from Wisewand input data
		$input_data = get_post_meta( $post_id, '_wisewand_input_data', true );
		if ( empty( $input_data ) ) {
			return;
		}

		$language = $this->determine_wpml_language( $input_data );
		if ( ! $language ) {
			return;
		}

		$this->set_post_language( $post_id, $language );

		// Handle translation linking if needed
		$this->handle_translation_linking( $post_id, $external_id, $language, $input_data );

		$this->logger->debug(
			'WPML language set for post',
			array(
				'post_id'     => $post_id,
				'language'    => $language,
				'external_id' => $external_id,
			)
		);
	}

	public function determine_wpml_language( array $input_data ) {
		if ( ! $this->options->is_wpml_active() ) {
			return null;
		}

		$wpml_settings = $this->options->get_wpml_settings();

		// Get language and country from input
		$lang    = strtolower( $input_data['lang'] ?? '' );
		$country = strtolower( $input_data['country'] ?? '' );

		$this->logger->debug(
			'Determining WPML language',
			array(
				'input_lang'    => $lang,
				'input_country' => $country,
				'wpml_mapping'  => $wpml_settings['lang_mapping'],
			)
		);

		if ( empty( $lang ) ) {
			return $wpml_settings['default_lang'] ?: null;
		}

		// Enhanced language detection with smart defaults
		$detected_language = $this->smart_language_detection( $lang, $country );

		if ( $detected_language ) {
			$this->logger->info(
				'Language detected for WPML',
				array(
					'wisewand_lang'    => $lang,
					'wisewand_country' => $country,
					'wpml_language'    => $detected_language,
				)
			);
			return $detected_language;
		}

		// Fall back to default language
		$default_lang = $wpml_settings['default_lang'] ?: $this->get_default_language();

		$this->logger->warning(
			'Using fallback language',
			array(
				'wisewand_lang'     => $lang,
				'fallback_language' => $default_lang,
			)
		);

		return $default_lang;
	}

	private function smart_language_detection( $lang, $country ) {
		global $sitepress;

		if ( ! $sitepress ) {
			return null;
		}

		$active_languages = $sitepress->get_active_languages();

		// 1. Try exact language-country combinations first
		$combinations_to_try = array(
			$lang . '-' . $country,  // en-us
			$lang . '_' . $country,  // en_us
			$lang,                   // en
		);

		foreach ( $combinations_to_try as $code ) {
			if ( isset( $active_languages[ $code ] ) ) {
				return $code;
			}
		}

		// 2. Try common language mappings
		$common_mappings = array(
			'en' => array( 'en', 'en-us', 'en_us' ),
			'fr' => array( 'fr', 'fr-fr', 'fr_fr' ),
			'de' => array( 'de', 'de-de', 'de_de' ),
			'es' => array( 'es', 'es-es', 'es_es' ),
			'it' => array( 'it', 'it-it', 'it_it' ),
		);

		if ( isset( $common_mappings[ $lang ] ) ) {
			foreach ( $common_mappings[ $lang ] as $possible_code ) {
				if ( isset( $active_languages[ $possible_code ] ) ) {
					return $possible_code;
				}
			}
		}

		// 3. Look for partial matches (e.g., 'en' article can use 'en-gb' WPML)
		foreach ( $active_languages as $wpml_code => $wpml_data ) {
			if ( strpos( $wpml_code, $lang ) === 0 ) {
				return $wpml_code;
			}
		}

		return null;
	}

	public function set_post_language( $post_id, $language_code ) {
		if ( ! $this->options->is_wpml_active() ) {
			return false;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return false;
		}

		// Validate language code
		if ( ! $this->is_wpml_language_active( $language_code ) ) {
			$this->logger->warning(
				'Invalid WPML language code',
				array(
					'language_code' => $language_code,
					'post_id'       => $post_id,
				)
			);
			return false;
		}

		// Set post language
		$post_type = get_post_type( $post_id );
		$trid      = $sitepress->get_element_trid( $post_id, "post_$post_type" );

		if ( ! $trid ) {
			// Create new translation group
			$sitepress->set_element_language_details(
				$post_id,
				"post_$post_type",
				false,
				$language_code
			);
		} else {
			// Update existing translation group
			$sitepress->set_element_language_details(
				$post_id,
				"post_$post_type",
				$trid,
				$language_code
			);
		}

		return true;
	}

	public function handle_translation_linking( $post_id, $external_id, $language, array $input_data ) {
		// Check if this is a translation of another post
		$translate_of_external_id = $input_data['translate_of_external_id'] ?? '';

		if ( empty( $translate_of_external_id ) ) {
			return;
		}

		// Find the original post
		$original_post = $this->find_post_by_external_id( $translate_of_external_id );

		if ( ! $original_post ) {
			$this->logger->warning(
				'Original post not found for translation',
				array(
					'translate_of_external_id' => $translate_of_external_id,
					'current_post_id'          => $post_id,
					'current_external_id'      => $external_id,
				)
			);
			return;
		}

		$this->link_as_translation( $post_id, $original_post->ID, $language );
	}

	public function link_as_translation( $translation_post_id, $original_post_id, $language_code ) {
		if ( ! $this->options->is_wpml_active() ) {
			return false;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return false;
		}

		$post_type    = get_post_type( $translation_post_id );
		$element_type = "post_$post_type";

		// Get original post's TRID
		$original_trid = $sitepress->get_element_trid( $original_post_id, $element_type );

		if ( ! $original_trid ) {
			$this->logger->error(
				'Original post has no TRID',
				array(
					'original_post_id'    => $original_post_id,
					'translation_post_id' => $translation_post_id,
				)
			);
			return false;
		}

		// Set the translation post to be part of the same translation group
		$sitepress->set_element_language_details(
			$translation_post_id,
			$element_type,
			$original_trid,
			$language_code
		);

		$this->logger->info(
			'Posts linked as translations',
			array(
				'original_post_id'    => $original_post_id,
				'translation_post_id' => $translation_post_id,
				'language_code'       => $language_code,
				'trid'                => $original_trid,
			)
		);

		return true;
	}

	public function get_post_translations( $post_id ) {
		if ( ! $this->options->is_wpml_active() ) {
			return array();
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return array();
		}

		$post_type = get_post_type( $post_id );
		$trid      = $sitepress->get_element_trid( $post_id, "post_$post_type" );

		if ( ! $trid ) {
			return array();
		}

		$translations = $sitepress->get_element_translations( $trid, "post_$post_type", true );

		$result = array();
		foreach ( $translations as $lang_code => $translation ) {
			if ( $translation->element_id != $post_id ) {
				$result[ $lang_code ] = array(
					'post_id'       => $translation->element_id,
					'language_code' => $lang_code,
					'original'      => $translation->original,
					'post_title'    => get_the_title( $translation->element_id ),
					'post_status'   => get_post_status( $translation->element_id ),
				);
			}
		}

		return $result;
	}

	public function find_post_by_external_id( $external_id, $language_code = null ) {
		global $wpdb;

		// Use conditional logic to build properly prepared queries
		if ( $this->options->is_wpml_active() && $language_code ) {
			// Query with WPML language filter
			$prepared_sql = $wpdb->prepare(
				"SELECT p.* FROM {$wpdb->posts} p
                INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
                WHERE pm.meta_key = '_wisewand_external_id'
                AND pm.meta_value = %s
                AND p.ID IN (
                    SELECT element_id FROM {$wpdb->prefix}icl_translations
                    WHERE language_code = %s AND element_type LIKE %s
                )
                LIMIT 1",
				$external_id,
				$language_code,
				'post_%'
			);
		} else {
			// Query without language filter
			$prepared_sql = $wpdb->prepare(
				"SELECT p.* FROM {$wpdb->posts} p
                INNER JOIN {$wpdb->postmeta} pm ON p.ID = pm.post_id
                WHERE pm.meta_key = '_wisewand_external_id'
                AND pm.meta_value = %s
                LIMIT 1",
				$external_id
			);
		}

        // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared, WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- $prepared_sql is already prepared using $wpdb->prepare() above; custom query for Wisewand external ID lookup with WPML language filtering
		return $wpdb->get_row( $prepared_sql );
	}

	public function is_wpml_language_active( $language_code ) {
		if ( ! $this->options->is_wpml_active() ) {
			return false;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return false;
		}

		$active_languages = $sitepress->get_active_languages();
		return isset( $active_languages[ $language_code ] );
	}

	public function get_wpml_languages() {
		if ( ! $this->options->is_wpml_active() ) {
			return array();
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return array();
		}

		return $sitepress->get_active_languages();
	}

	public function get_default_language() {
		if ( ! $this->options->is_wpml_active() ) {
			return null;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return null;
		}

		return $sitepress->get_default_language();
	}

	public function get_suggested_language_mapping() {
		$suggestions = array();

		// Common language mappings
		$common_mappings = array(
			'en'    => 'en',
			'en-us' => 'en',
			'en-gb' => 'en',
			'fr'    => 'fr',
			'fr-fr' => 'fr',
			'fr-ca' => 'fr',
			'de'    => 'de',
			'de-de' => 'de',
			'es'    => 'es',
			'es-es' => 'es',
			'it'    => 'it',
			'it-it' => 'it',
			'pt'    => 'pt',
			'pt-br' => 'pt-br',
			'nl'    => 'nl',
			'pl'    => 'pl',
			'ru'    => 'ru',
			'ja'    => 'ja',
			'ko'    => 'ko',
			'zh'    => 'zh-hans',
			'zh-cn' => 'zh-hans',
			'zh-tw' => 'zh-hant',
		);

		$active_languages = $this->get_wpml_languages();

		foreach ( $common_mappings as $wisewand_code => $wpml_code ) {
			if ( isset( $active_languages[ $wpml_code ] ) ) {
				$suggestions[ $wisewand_code ] = $wpml_code;
			}
		}

		return $suggestions;
	}

	public function validate_language_mapping( $mapping ) {
		$errors           = array();
		$active_languages = $this->get_wpml_languages();

		foreach ( $mapping as $wisewand_code => $wpml_code ) {
			if ( ! empty( $wpml_code ) && ! isset( $active_languages[ $wpml_code ] ) ) {
				$errors[ $wisewand_code ] = sprintf(
					/* translators: %s: WPML language code (e.g., 'en', 'fr', 'es') */
					__( 'WPML language code "%s" is not active', 'wisewand-ai-content-writer-seo-content-generator' ),
					$wpml_code
				);
			}
		}

		return $errors;
	}

	public function get_post_language( $post_id ) {
		if ( ! $this->options->is_wpml_active() ) {
			return null;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return null;
		}

		$post_type = get_post_type( $post_id );
		return $sitepress->get_language_for_element( $post_id, "post_$post_type" );
	}

	public function duplicate_to_language( $source_post_id, $target_language, $copy_content = true ) {
		if ( ! $this->options->is_wpml_active() ) {
			return new \WP_Error(
				'wisewand_wpml_not_active',
				__( 'WPML is not active', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		$source_post = get_post( $source_post_id );
		if ( ! $source_post ) {
			return new \WP_Error(
				'wisewand_post_not_found',
				__( 'Source post not found', 'wisewand-ai-content-writer-seo-content-generator' )
			);
		}

		// Create duplicate post data
		$duplicate_data = array(
			'post_title'     => $source_post->post_title,
			'post_content'   => $copy_content ? $source_post->post_content : '',
			'post_excerpt'   => $source_post->post_excerpt,
			'post_status'    => 'draft', // Always create as draft
			'post_type'      => $source_post->post_type,
			'post_author'    => $source_post->post_author,
			'post_parent'    => $source_post->post_parent,
			'menu_order'     => $source_post->menu_order,
			'comment_status' => $source_post->comment_status,
			'ping_status'    => $source_post->ping_status,
		);

		$duplicate_id = wp_insert_post( $duplicate_data );

		if ( is_wp_error( $duplicate_id ) ) {
			return $duplicate_id;
		}

		// Set language and link as translation
		$this->set_post_language( $duplicate_id, $target_language );
		$this->link_as_translation( $duplicate_id, $source_post_id, $target_language );

		// Copy relevant meta data
		$this->copy_wisewand_meta( $source_post_id, $duplicate_id );

		$this->logger->info(
			'Post duplicated to new language',
			array(
				'source_post_id'    => $source_post_id,
				'duplicate_post_id' => $duplicate_id,
				'target_language'   => $target_language,
			)
		);

		return $duplicate_id;
	}

	private function copy_wisewand_meta( $source_post_id, $target_post_id ) {
		$meta_keys_to_copy = array(
			'_wisewand_input_data',
			'_wisewand_schema_json',
			'_wisewand_audio_url',
			'_wisewand_audio_id',
			'_wisewand_gallery_images',
		);

		foreach ( $meta_keys_to_copy as $meta_key ) {
			$value = get_post_meta( $source_post_id, $meta_key, true );
			if ( ! empty( $value ) ) {
				update_post_meta( $target_post_id, $meta_key, $value );
			}
		}

		// Generate new external ID for the duplicate
		$original_external_id = get_post_meta( $source_post_id, '_wisewand_external_id', true );
		if ( $original_external_id ) {
			$language        = $this->get_post_language( $target_post_id );
			$new_external_id = $original_external_id . '_' . $language;
			update_post_meta( $target_post_id, '_wisewand_external_id', $new_external_id );
		}
	}

	public function get_translation_status( $post_id ) {
		if ( ! $this->options->is_wpml_active() ) {
			return null;
		}

		$post_language       = $this->get_post_language( $post_id );
		$translations        = $this->get_post_translations( $post_id );
		$available_languages = $this->get_wpml_languages();

		$status = array(
			'current_language'      => $post_language,
			'available_languages'   => array_keys( $available_languages ),
			'existing_translations' => array_keys( $translations ),
			'missing_translations'  => array(),
		);

		foreach ( $available_languages as $lang_code => $lang_data ) {
			if ( $lang_code !== $post_language && ! isset( $translations[ $lang_code ] ) ) {
				$status['missing_translations'][] = $lang_code;
			}
		}

		return $status;
	}

	public function cleanup_translation_group( $post_id ) {
		if ( ! $this->options->is_wpml_active() ) {
			return;
		}

		global $sitepress;

		if ( ! $sitepress ) {
			return;
		}

		$post_type = get_post_type( $post_id );
		$trid      = $sitepress->get_element_trid( $post_id, "post_$post_type" );

		if ( ! $trid ) {
			return;
		}

		// Get all translations in the group
		$translations = $sitepress->get_element_translations( $trid, "post_$post_type", true );

		// Remove the deleted post from the translation group
		$sitepress->delete_element_translation( $trid, "post_$post_type", $post_id );

		$this->logger->debug(
			'Post removed from WPML translation group',
			array(
				'post_id'                => $post_id,
				'trid'                   => $trid,
				'remaining_translations' => count( $translations ) - 1,
			)
		);
	}
}
