<?php
/*
Plugin Name:LocoAI – Auto Translate for Loco Translate (Pro)
Description:Auto translation addon for Loco Translate – translate plugin & theme strings using AI tools like Google Translate, DeepL, ChatGPT, Gemini, OpenAI & more.
Version:2.0.9
License:GPLv3
Text Domain:loco-translate-addon
Domain Path:languages
Author:Cool Plugins
Author URI:https://example.net/?utm_source=atlt_plugin&utm_medium=inside&utm_campaign=author_page&utm_content=dashboard
 */

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

define( 'ATLT_PRO_FILE', __FILE__ );
define( 'ATLT_PRO_URL', plugin_dir_url( ATLT_PRO_FILE ) );
define( 'ATLT_PRO_PATH', plugin_dir_path( ATLT_PRO_FILE ) );
define( 'ATLT_PRO_VERSION', '2.0.9' );
define( 'ATLT_PLUGIN_BASENAME', plugin_basename( ATLT_PRO_FILE ) );

if ( ! defined( 'ATLT_FEEDBACK_API' ) ) {
    define( 'ATLT_FEEDBACK_API', "https://feedback.example.net/" );
}

require_once __DIR__ . '/vendor/autoload.php';

use Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services\API\Enums\AI_Capability;
use Loco_Automatic_Translate_Addon_Pro\AI_Translate\Services\API\Helpers;
use Loco_Automatic_Translate_Addon_Pro\AI_Translate\Plugin_Main;


/**
 * @package LocoAI – Auto Translate for Loco Translate (Pro)
 * @version 1.4.1
 */

if ( ! class_exists( 'LocoAutoTranslateAddonPro' ) ) {

	/** Singleton ************************************/
	final class LocoAutoTranslateAddonPro {


		/**
		 * The unique instance of the plugin.
		 *
		 * @var LocoAutoTranslateAddonPro
		 */
		private static $instance;

		/**
		 * Gets an instance of plugin.
		 */
		public static function get_instance() {
			if ( null === self::$instance ) {
				self::$instance = new self();

				// register all hooks
				self::$instance->register();

			}

			return self::$instance;
		}
		/**
		 * Constructor.
		 */
		public function __construct() {
			 // Setup your plugin object here
			 $this->init_ai_translate_service();

			 // Initialize feedback notice
			 $this->init_feedback_notice();

			// Add CPT Dashboard initialization
			if (!class_exists('Atlt_Dashboard')) {
				require_once ATLT_PRO_PATH . 'admin/cpt_dashboard/cpt_dashboard.php';
				$dashboard = Atlt_Dashboard::instance();
			}
		}

		/**
		 * Registers our plugin with WordPress.
		 */
		public static function register() {

			 $thisPlugin = self::$instance;
			register_activation_hook( ATLT_PRO_FILE, array( $thisPlugin, 'atlt_activate' ) );
			register_deactivation_hook( ATLT_PRO_FILE, array( $thisPlugin, 'atlt_deactivate' ) );

			// run actions and filter only at admin end.
			if ( is_admin() ) {

				add_action( 'plugins_loaded', array( $thisPlugin, 'atlt_check_required_loco_plugin' ) );
				add_action( 'init', array( $thisPlugin, 'atlt_load_textdomain' ) );
				// add notice to use latest loco translate addon
				add_action( 'init', array( $thisPlugin, 'atlt_verify_loco_version' ) );
				add_action( 'init', array( $thisPlugin, 'onInit' ) );
				/*** Plugin Setting Page Link inside All Plugins List */
				add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $thisPlugin, 'atlt_settings_page_link' ) );

				add_filter('plugin_row_meta', array($thisPlugin,'atlt_add_docs_link_to_plugin_meta'), 10, 2);

				add_action( 'plugins_loaded', array( $thisPlugin, 'atlt_include_files' ) );
				add_action( 'admin_enqueue_scripts', array( $thisPlugin, 'atlt_enqueue_scripts' ) );

				// Add the action to hide unrelated notices
				if(isset($_GET['page']) && $_GET['page'] == 'loco-atlt-dashboard'){
					add_action('admin_print_scripts', array($thisPlugin, 'atlt_hide_unrelated_notices'));
				}

				/*since version 2.1 */
				add_filter( 'loco_api_providers', array( $thisPlugin, 'atlt_register_api' ), 10, 1 );
				add_action( 'loco_api_ajax', array( $thisPlugin, 'atlt_ajax_init' ), 0, 0 );
				add_action( 'wp_ajax_save_all_translations', array( $thisPlugin, 'atlt_save_translations_handler' ) );
				add_action( 'wp_ajax_atlt_cool_plugins_admin_notice', array( $thisPlugin, 'atlt_admin_notice_dismiss' ) );
				add_action('wp_ajax_atlt_geminiAI_openAI_ajax_handler', array($thisPlugin, 'atlt_geminiAI_openAI_ajax_handler'));

				/*
				since version 2.0
				Yandex translate widget integration
				*/
				// add no translate attribute in html tag
				if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'file-edit' ) {
					add_action( 'admin_footer', array( $thisPlugin, 'atlt_load_ytranslate_scripts' ), 100 );
					add_action( 'admin_footer', array( $thisPlugin, 'atlt_load_gtranslate_scripts' ), 100 );
					add_filter( 'admin_body_class', array( $thisPlugin, 'atlt_add_custom_class' ) );

				}

				add_action( 'init', array( $thisPlugin, 'atlt_set_gtranslate_cookie' ) );

				add_action( 'after_plugin_row_' . ATLT_PLUGIN_BASENAME, array( $thisPlugin, 'atlt_plugin_custom_notice' ), 10, 2 );
				add_filter( 'site_transient_update_plugins', array( $thisPlugin, 'atlt_hide_plugin_update_notice' ) );
			}

		}

		public function atlt_add_docs_link_to_plugin_meta($links, $file) {
			if (plugin_basename(__FILE__) === $file) {
				$docs_link = '<a href="https://example.com/docs/" target="_blank">Docs</a>';
				$links[] = $docs_link;
			}
			return $links;
		}

		/**
		 * Display custom update notices for the LocoAI Pro plugin in the WordPress plugins list table.
		 *
		 * This function checks the plugin's license status and update availability, and then conditionally
		 * displays messages in the plugin list:
		 *
		 * - If an update is available but the license key is not entered, it shows a warning to activate the license.
		 * - If the license or support period has expired, it displays a renewal message with appropriate links.
		 * - If the license is valid, no custom notice is shown.
		 *
		 * Hooked into the 'after_plugin_row' action to insert notices below the plugin row.
		 *
		 * @param string $plugin_file The plugin file path relative to the plugins directory.
		 * @param array  $plugin_data An array of plugin header data.
		*/

		public function atlt_plugin_custom_notice( $plugin_file, $plugin_data ) {
			
    				// Get license info and update info for the plugin
		$license_info = LocoAutomaticTranslateAddonProBase::GetRegisterInfo();
		$update_info = LocoAutomaticTranslateAddonProBase::getInstance()->__plugin_updateInfo();

		// Get version available message using common helper
		$version_available_message = ProHelpers::getVersionAvailableMessage();
		$plugin_basename = plugin_basename(__FILE__);

		if ( ! LocoAutomaticTranslateAddonPro::$form_status &&  $plugin_basename === ATLT_PLUGIN_BASENAME ) {
				
				$renew_link = wp_kses_post(
					__( $version_available_message.' Please <a href="admin.php?page=loco-atlt-dashboard&tab=license">enter your license key</a> to enable automatic updates and premium support for LocoAI – Auto Translate for Loco Translate (Pro)', 'atlt' ),
					array(
						'a' => array(
							'href' => array()
						)
					)
				);

			} else {

				// Check if new version is available and license is invalid/expired
				if ( empty( $update_info->download_link ) ) {
					
					$is_expired = (empty($update_info->is_downloadable) ) ? 'license' : 'support';
					
					$message = ' Your ' . $is_expired . ' has expired,';
					$renew_text = ( ! empty( $license_info->market ) && $license_info->market === 'E' ) 
						? 'Please renew your ' . $is_expired . ' to continue receiving automatic updates and priority support.'
						: 'Please <a href="https://my.example.net/account/subscriptions/" target="_blank">Renew now</a> to continue receiving automatic updates and priority support.';
					
					$renew_link = $version_available_message . $message . ' ' . $renew_text;
				}
			}

			if ( ! empty( $renew_link ) ) {

					?>
					<tr class="plugin-update-tr active atlt-pro">
						<td colspan="4" class="plugin-update colspanchange">
							<div class="update-message notice inline notice-warning notice-alt"> 
								<p><?php echo wp_kses_post( $renew_link ); ?></p>
							</div>
						</td>
					</tr>
					<?php
			}
		}

		/**
		 * Hide WordPress core plugin update notice when license is not valid
		 * 
		 * @param object $transient The site transient for plugin updates
		 * @return object Modified transient
		 */
		public function atlt_hide_plugin_update_notice( $transient ) {

			$update_info = LocoAutomaticTranslateAddonProBase::getInstance()->__plugin_updateInfo();

				if ( empty($update_info->download_link)){
					if ( isset( $transient->response ) && isset( $transient->response[ATLT_PLUGIN_BASENAME] ) ) {
						unset( $transient->response[ATLT_PLUGIN_BASENAME] );
					}
				}
			
			return $transient;
		}

		public function init_feedback_notice() {
			if (is_admin()) {

				if(!class_exists('CPFM_Feedback_Notice')){
					require_once ATLT_PRO_PATH . '/admin/feedback/cpfm-common-notice.php';
					
				}

			add_action('cpfm_register_notice', function () {
                if (!class_exists('CPFM_Feedback_Notice') || !current_user_can('manage_options')) {
                    return;
                }
				
                $notice = [
                    'title' => __('Translations Plugins by Cool Plugins', 'ccpw'),
                    'message' => __('Help us make this plugin more compatible with your site by sharing non-sensitive site data.', 'cool-plugins-feedback'),
                    'pages' => ['loco-atlt-dashboard'],
                    'always_show_on' => ['loco-atlt-dashboard'], // This enables auto-show
                    'plugin_name'=>'atlt'
                ];
                CPFM_Feedback_Notice::cpfm_register_notice('cool_translations', $notice);
                    if (!isset($GLOBALS['cool_plugins_feedback'])) {
                        $GLOBALS['cool_plugins_feedback'] = [];
                    }
                    $GLOBALS['cool_plugins_feedback']['cool_translations'][] = $notice;
            });

            add_action('cpfm_after_opt_in_atlt', function($category) {
                if ($category === 'cool_translations') {
                    ATLT_cronjob::atlt_send_data();
					$options = get_option('atlt_feedback_opt_in');
					$options = 'yes';
					update_option('atlt_feedback_opt_in', $options);	
                }
            });
			}
		}

		public function init_ai_translate_service() {
			// Initialize Plugin_Main if available
			$plugin_main = new Loco_Automatic_Translate_Addon_Pro\AI_Translate\Plugin_Main( ATLT_PRO_FILE );
			$plugin_main->add_hooks();
			
			// Include API file
			require_once plugin_dir_path( __FILE__ ) . 'includes/ai-translate/api.php';
			require_once ATLT_PRO_PATH . '/admin/feedback/cron/atlt-cron.php';
			$cron = new ATLT_cronjob();
			$cron->atlt_cron_init_hooks();
		}
		
		/*
		|----------------------------------------------------------------------	
		| Redirect to plugin page after activation
		|----------------------------------------------------------------------
		*/

		public function atlt_plugin_redirection($plugin) {
			if (plugin_basename(__FILE__) === $plugin) {
				wp_safe_redirect( admin_url( 'admin.php?page=loco-atlt-dashboard' ) );
				exit;
			}
		}
		/*
		|----------------------------------------------------------------------
		| GeminiAI & OpenAI 
		|----------------------------------------------------------------------
		*/

		
		function atlt_geminiAI_openAI_ajax_handler() {
			check_ajax_referer('loco-addon-nonces', 'nonce');

			// Validate the source_data input
			if (!isset($_POST['source_data']) || !is_array($_POST['source_data'])) {
				wp_send_json_error('Invalid request: source_data is missing or not an array.');
				return;
			}

			$source = $_POST['source_data']['source'];
			$locale = sanitize_text_field($_POST['source_data']['locale']['label']);
			$selectedApi = sanitize_text_field($_POST['source_data']['selectedApi']);

			// Only return the translation in the format of a JSON object with the keys being numeric values (matching the source keys), and the values being the translated strings

			$content = sprintf(
				'Instruction 1: [%%s, %%d, %%S, %%D, %%s, %%S, %%d, %%D, %%س] These placeholders are special and should not be translated. 
				 Instruction 2: Avoid repeating translations and skip any strings if necessary. If a string is skipped, maintain its original key. 
				 Instruction 3: the translation in the format of a JSON object with the keys being numeric values (matching the source keys), and the values being the translated strings. 
				 Instruction 4: Use "\\" to escape special characters like \" and " to ensure valid JSON format. 
				 Instruction 5: Translate the provided JSON array into %s language, regardless of whether the values are the same and Ensure the JSON is well-formed and complete. Please ensure that the output follows the format: {"key(numeric value)": "(translations of the strings in %s language)}" Strings are :- %s',
				$locale,
				$locale,
				json_encode($source)
			);

			// Check if the selected API is available
			if ( ai_translate()->is_service_available($selectedApi) ) {
				$service = ai_translate()->get_available_service($selectedApi);

				try {
					$candidates = $service
						->get_model(
							array(
								'feature'      => 'my-test-feature',
								'capabilities' => array( AI_Capability::TEXT_GENERATION ),
							)
						)->generate_text($content);

					$text = Helpers::get_text_from_contents(
						Helpers::get_candidate_contents( $candidates )
					);

					$cleanText = preg_replace('/(^```json\n|```$)/', '', $text);
				
					wp_send_json_success(json_decode($cleanText));

				} catch ( Exception $e ) {
					wp_send_json_error('Error during text generation: ' . $e->getMessage());
				}
			} else {
				wp_send_json_error(sprintf(
					'%s service is not available.',
					$selectedApi === 'google' ? 'GeminiAI' : ucfirst($selectedApi)
				));
			}
		}

		
		
		public function atlt_admin_notice_dismiss() {
			$id       = isset( $_REQUEST['id'] ) ? sanitize_text_field( $_REQUEST['id'] ) : '';
			$wp_nonce = $id . '_notice_nonce';
			if ( ! check_ajax_referer( $wp_nonce, '_nonce', false ) ) {
				die('nonce verification failed!');
			} else {
				$us = update_option($id.'_remove_notice','yes');
				die('Admin message removed!');
			}
		}
		public function onInit() {
			if ( in_array(
				'automatic-translator-addon-for-loco-translate/automatic-translator-addon-for-loco-translate.php',
				apply_filters( 'active_plugins', get_option( 'active_plugins' ) )
			) ) {
				include_once ABSPATH . 'wp-admin/includes/plugin.php';
				// Ensure the plugin is deactivated securely
				if ( current_user_can( 'activate_plugins' ) ) {
					deactivate_plugins( 'automatic-translator-addon-for-loco-translate/automatic-translator-addon-for-loco-translate.php' );
					$get_opt_in = get_option('atlt_feedback_opt_in');

					if ($get_opt_in =='yes' && !wp_next_scheduled('atlt_extra_data_update')) {

						wp_schedule_event(time(), 'every_30_days', 'atlt_extra_data_update');
					}
				}
				return;
			}

			
		}
		/*
		|----------------------------------------------------------------------
		| Register API Manager inside Loco Translate Plugin
		|----------------------------------------------------------------------
		*/
		function atlt_register_api( array $apis ) {
			$apis[] = array(
				'id'   => 'loco_auto',
				'key'  => 'NULL',
				'url'  => 'https://example.com/',
				'name' => 'Automatic Translate Addon',
			);
			return $apis;
		}
		/*
		|----------------------------------------------------------------------
		| Auto Translate Request handler
		|----------------------------------------------------------------------
		*/
		function atlt_ajax_init() {
			if( version_compare( loco_plugin_version(), '2.7', '>=' ) ){
				add_filter( 'loco_api_translate_loco_auto', array( self::$instance, 'atlt_loco_auto_translator_process_batch' ), 0, 4 );
			}
			else {
				add_filter('loco_api_translate_loco_auto',array( self::$instance, 'atlt_loco_auto_translator_process_batch_legacy' ), 0,3);
			}
		}
		
		public function atlt_loco_auto_translator_process_batch_legacy( array $sources, Loco_Locale $locale, array $config ) {
			$items = [];
			foreach( $sources as $text ){
				$items[] = [ 'source' => $text ];
			}
			return $this->atlt_loco_auto_translator_process_batch( [], $items, $locale, $config );
		}

		/**
		 * Hook fired as a filter for the "loco_auto" translation API.
		 *
		 * @param array       $sources Input strings.
		 * @param Loco_Locale $Locale  Target locale for translations.
		 * @param array       $config  Our own API configuration.
		 *
		 * @return array Output strings.
		 */
		function atlt_loco_auto_translator_process_batch(array $targets, array $items, Loco_Locale $locale, array $config) {
			$targets = array();

			// Extract domain from the referrer URL
			$url_data   = $this->atlt_parse_query( $_SERVER['HTTP_REFERER'] );
			$domain     = isset( $url_data['domain'] ) && ! empty( $url_data['domain'] ) ? $url_data['domain'] : 'temp';
			$lang       = sanitize_text_field( $locale->lang );
			$region     = sanitize_text_field( $locale->region );
			$project_id = $domain . '-' . $lang . '-' . $region;

			// Combine transient parts if available
			$allString = array();
			$translationData = array();
			for ( $i = 0; $i <= 4; $i++ ) {
				$transient_data = get_transient( $project_id . '-part-' . $i );

				if ( ! empty( $transient_data ) ) {
					if (isset( $transient_data['strings'] )) {
						$allString = array_merge( $allString, $transient_data['strings'] );
					}
				}
			}
			if (!empty($allString)) {
				foreach ($items as $i => $item) {
					$normalizedSource = preg_replace('/\s+/', ' ', trim($item['source']));
		
					// Find the index of the normalized source string in the cached strings
					$index = array_search($normalizedSource, array_column($allString, 'source'));
					if (is_numeric($index) && isset($allString[$index]['target'])) {
						$targets[$i] = $allString[$index]['target'];
					} else {
						$targets[$i] = '';
					}
				}

				return $targets;
			} else {
				throw new Loco_error_Exception( 'Please translate strings using the Auto Translate addon button first.' );
			}

		}

		/**
		 * Parse the query string from the URL.
		 *
		 * @param string $var URL to parse.
		 *
		 * @return array Parsed query parameters.
		 */
		function atlt_parse_query( $var ) {
			$var = parse_url( $var, PHP_URL_QUERY );
			$var = html_entity_decode( $var );
			$var = explode( '&', $var );
			$arr = array();

			foreach ( $var as $val ) {
				$x            = explode( '=', $val );
				$arr[ $x[0] ] = $x[1];
			}

			unset( $val, $x, $var );
			return $arr;
		}

		/*
		|----------------------------------------------------------------------
		| Save string translation inside cache for later use
		|----------------------------------------------------------------------
		*/
		 // save translations inside transient cache for later use
		 function atlt_save_translations_handler() {

			check_ajax_referer( 'loco-addon-nonces', 'wpnonce' );

			if ( isset( $_POST['data'] ) && ! empty( $_POST['data'] ) && isset( $_POST['part'] ) ) {

				$allStrings = json_decode( stripslashes( $_POST['data'] ), true );
				$translationData = isset($_POST['translation_data']) ? json_decode(stripslashes($_POST['translation_data']), true) : null;

				if ( empty( $allStrings ) ) {
					echo json_encode(
						array(
							'success' => false,
							'error'   => 'No data found in the request. Unable to save translations.',
						)
					);
					wp_die();
				}

				// Determine the project ID based on the loop value
				$projectId = $_POST['project-id'] . $_POST['part'];
				
				$dataToStore = array(
					'strings' => $allStrings,
				);

				// Save the combined data in transient
				$rs = set_transient( $projectId, $dataToStore, 5 * MINUTE_IN_SECONDS );
				echo json_encode(
					array(
						'success'  => true,
						'message'  => 'Translations successfully stored in the cache.',
						'response' => $rs == true ? 'saved' : 'cache already exists',
					)
				);

				if ( $_POST['part'] === '-part-0') {
					// Safely extract and sanitize translation metadata
					$metadata = array(
						'translation_provider' => isset($translationData['translation_provider']) ? sanitize_text_field($translationData['translation_provider']) : '',
						'string_count' => isset($translationData['string_count']) ? absint($translationData['string_count']) : 0,
						'character_count' => isset($translationData['character_count']) ? absint($translationData['character_count']) : 0,
						'time_taken' => isset($translationData['time_taken']) ? absint($translationData['time_taken']) : 0,
						'pluginORthemeName' => isset($translationData['pluginORthemeName']) ? sanitize_text_field($translationData['pluginORthemeName']) : '',
						'target_language' => isset($translationData['target_language']) ? sanitize_text_field($translationData['target_language']) : ''
					);

					if (class_exists('Atlt_Dashboard') ) {
						Atlt_Dashboard::store_options(
							'atlt',
							'plugins_themes',
							'update',
							array(
								'plugins_themes' => $metadata['pluginORthemeName'],
								'service_provider' => $metadata['translation_provider'],
								'source_language' => 'en',
								'target_language' => $metadata['target_language'],
								'time_taken' => $metadata['time_taken'],
								'string_count' => $metadata['string_count'],
								'character_count' => $metadata['character_count'],
								'date_time' => date('Y-m-d H:i:s'),
								'version_type' => 'pro'
							)
						);
					}
				}

			} else {
				// Security check failed or missing parameters
				echo json_encode( array( 'error' => 'Invalid request. Missing required parameters.' ) );
				wp_die();
			}
			wp_die();
		}


		/*
		|----------------------------------------------------------------------
		| Yandex Translate Widget Integartions
		| add no translate attribute in html tag
		|----------------------------------------------------------------------
		*/
		function atlt_load_ytranslate_scripts() {
			if ( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'file-edit' ) {
				echo "<script>document.getElementsByTagName('html')[0].setAttribute('translate', 'no');</script>";
			}
		}
		 // add no translate class in admin body to disable whole page translation
		function atlt_add_custom_class( $classes ) {
			return "$classes notranslate";
		}

		/*
		|----------------------------------------------------------------------
		| Google Translate Widget integrations
		| load Google Translate widget scripts
		|----------------------------------------------------------------------
		*/
		function atlt_load_gtranslate_scripts() {

			echo "<script>
           function gTranslateWidget() {
               var locale=locoConf.conf.locale;
               var defaultcode = locale.lang?locale.lang:null;
               switch(defaultcode){
                   case 'kir':
                       defaultlang='ky';
                       break;
                   case 'oci':
                       defaultlang='oc';
                       break;
                   case 'bel':
                   defaultlang='be';
                   break;
                   case 'he':
                       defaultlang='iw';
                       break;
                   case'snd':
                       defaultlang='sd';
                   break;
                   case 'jv':
                       defaultlang='jw';
                       break;
                       case 'nb':
                           defaultlang='no';
                           break;
             
                           case 'nn':
                             defaultlang='no';
                             break;
                   default:
                   defaultlang=defaultcode;
               break;
               return defaultlang;
               }
              if(defaultlang=='zh'){
              new google.translate.TranslateElement(
                   {
                   pageLanguage: 'en',
                   includedLanguages: 'zh-CN,zh-TW',
                   defaultLanguage: 'zh-CN,zh-TW',
                   multilanguagePage: true
                   },
                   'google_translate_element'
               );
           }
           else{
               new google.translate.TranslateElement(
                   {
                   pageLanguage: 'en',
                   includedLanguages: defaultlang,
                   defaultLanguage: defaultlang,
                   multilanguagePage: true
                   },
                   'google_translate_element'
               );
           }
           }
           </script>
           <script src='https://translate.google.com/translate_a/element.js'></script>
           ";
		}

		// set default option in google translate widget using cookie
		function atlt_set_gtranslate_cookie() {
			// setting your cookies there
			if ( ! isset( $_COOKIE['googtrans'] ) ) {
				setcookie( 'googtrans', '/en/Select Language', 2147483647 );
			}
		}
		/*
		|----------------------------------------------------------------------
		| check if required "Loco Translate" plugin is active
		| also register the plugin text domain
		|----------------------------------------------------------------------
		*/
		public function atlt_load_textdomain() {
			// load language files
			load_plugin_textdomain( 'loco-auto-translate', false, basename( dirname( __FILE__ ) ) . '/languages/' );
			if (!get_option('atlt_pro_initial_save_version')) {
				add_option('atlt_pro_initial_save_version', ATLT_PRO_VERSION);
			}
		}

		public function atlt_check_required_loco_plugin() {
			if ( ! function_exists( 'loco_plugin_self' ) ) {
				add_action( 'admin_notices', array( self::$instance, 'atlt_plugin_required_admin_notice' ) );
			}
		}
		/*
		|----------------------------------------------------------------------
		| Notice to 'Admin' if "Loco Translate" is not active
		|----------------------------------------------------------------------
		*/
		public function atlt_plugin_required_admin_notice() {
			if ( current_user_can( 'activate_plugins' ) ) {
				$url         = 'plugin-install.php?tab=plugin-information&plugin=loco-translate&TB_iframe=true';
				$title       = 'Loco Translate';
				$plugin_info = get_plugin_data( __FILE__, true, true );

				// Sanitize the output to prevent XSS
				$plugin_name = esc_html( $plugin_info['Name'] );
				$escaped_url = esc_url( $url );
				$escaped_title = esc_attr( $title );

				echo '<div class="error"><p>' .
				sprintf(
					__(
						'In order to use <strong>%1$s</strong> plugin, please install and activate the latest version of <a href="%2$s" class="thickbox" title="%3$s">%4$s</a>',
						'automatic-translator-addon-for-loco-translate'
					),
					$plugin_name,
					$escaped_url,
					$escaped_title,
					$escaped_title
				) . '.</p></div>';

				deactivate_plugins( __FILE__ );
			}
		}
		/*
		|----------------------------------------------------------------------
		| create 'settings' link in plugins page
		|----------------------------------------------------------------------
		*/
		public function atlt_settings_page_link( $links ) {
			$links[] = '<a style="font-weight:bold" href="' . esc_url( get_admin_url( null, 'admin.php?page=loco-atlt-dashboard' ) ) . '">Settings</a>';
			return $links;
		}


		/*
		|----------------------------------------------------------------------
		| check User Status
		|----------------------------------------------------------------------
		*/
		public function atlt_verify_loco_version() {
			if ( function_exists( 'loco_plugin_version' ) ) {
				 $locoV = loco_plugin_version();
				if ( version_compare( $locoV, '2.4.0', '<' ) ) {
					add_action( 'admin_notices', array( self::$instance, 'use_loco_latest_version_notice' ) );
				}
			}
		}
		/*
		|----------------------------------------------------------------------
		| Notice to use latest version of Loco Translate plugin
		|----------------------------------------------------------------------
		*/
		public function use_loco_latest_version_notice() {
			if ( current_user_can( 'activate_plugins' ) ) {
				$url         = 'plugin-install.php?tab=plugin-information&plugin=loco-translate&TB_iframe=true';
				$title       = 'Loco Translate';
				$plugin_info = get_plugin_data( __FILE__, true, true );

				// Sanitize the plugin name and version for output
				$plugin_name = esc_html($plugin_info['Name']);
				$plugin_version = esc_html($plugin_info['Version']);
				$escaped_url = esc_url($url);
				$escaped_title = esc_attr($title);

				echo '<div class="error"><p>' .
				sprintf(
					__(
						'In order to use <strong>%1$s</strong> (version <strong>%2$s</strong>), Please update <a href="%3$s" class="thickbox" title="%4$s">%5$s</a> official plugin to a latest version (2.4.0 or upper)',
						'automatic-translator-addon-for-loco-translate'
					),
					$plugin_name,
					$plugin_version,
					$escaped_url,
					$escaped_title,
					$escaped_title
				) . '.</p></div>';
			}
		}

		/*
		|----------------------------------------------------------------------
		| required php files
		|----------------------------------------------------------------------
		*/
		public function atlt_include_files() {

			require_once ATLT_PRO_PATH . '/includes/Register/LocoAutomaticTranslateAddonProBase.php';
			new LocoAutomaticTranslateAddonProBase( ATLT_PRO_FILE );
			require_once ATLT_PRO_PATH . 'includes/Helpers/ProHelpers.php';
			require_once ATLT_PRO_PATH . 'includes/Register/LocoAutomaticTranslateAddonPro.php';
			// require_once ATLT_PRO_PATH . 'includes/ReviewNotice/atlt-feedback-notice.php';
			// Get rating values with default 'no'
			$ratingDiv = get_option('atlt-pro-ratingDiv', 'no');
			$alreadyRated = get_option('atlt-already-rated', 'no');

			// Check if the user has already rated
			if ($ratingDiv !== 'yes' && $alreadyRated !== 'yes' && class_exists('Atlt_Dashboard')) {
				Atlt_Dashboard::review_notice(
					'atlt', 
					'LocoAI – Auto Translate for Loco Translate (Pro)', 
					'https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post', 
					ATLT_PRO_URL . '/assets/images/atlt-logo.png'
				);
			}
		}

		/*
		|------------------------------------------------------------------------
		|  Hide unrelated notices
		|------------------------------------------------------------------------
		*/

		public function atlt_hide_unrelated_notices()
			{ // phpcs:ignore Generic.Metrics.CyclomaticComplexity.MaxExceeded, Generic.Metrics.NestingLevel.MaxExceeded
				$cfkef_pages = false;

				if(isset($_GET['page']) && $_GET['page'] == 'loco-atlt-dashboard'){
					$cfkef_pages = true;
				}

				if ($cfkef_pages) {
					global $wp_filter;
					// Define rules to remove callbacks.
					$rules = [
						'user_admin_notices' => [], // remove all callbacks.
						'admin_notices'      => [],
						'all_admin_notices'  => [],
						'admin_footer'       => [
							'render_delayed_admin_notices', // remove this particular callback.
						],
					];
					$notice_types = array_keys($rules);
					foreach ($notice_types as $notice_type) {
						if (empty($wp_filter[$notice_type]->callbacks) || ! is_array($wp_filter[$notice_type]->callbacks)) {
							continue;
						}
						$remove_all_filters = empty($rules[$notice_type]);
						foreach ($wp_filter[$notice_type]->callbacks as $priority => $hooks) {
							foreach ($hooks as $name => $arr) {
								if (is_object($arr['function']) && is_callable($arr['function'])) {
									if ($remove_all_filters) {
										unset($wp_filter[$notice_type]->callbacks[$priority][$name]);
									}
									continue;
								}
								$class = ! empty($arr['function'][0]) && is_object($arr['function'][0]) ? strtolower(get_class($arr['function'][0])) : '';
								// Remove all callbacks except WPForms notices.
								if ($remove_all_filters && strpos($class, 'wpforms') === false) {
									unset($wp_filter[$notice_type]->callbacks[$priority][$name]);
									continue;
								}
								$cb = is_array($arr['function']) ? $arr['function'][1] : $arr['function'];
								// Remove a specific callback.
								if (! $remove_all_filters) {
									if (in_array($cb, $rules[$notice_type], true)) {
										unset($wp_filter[$notice_type]->callbacks[$priority][$name]);
									}
									continue;
								}
							}
						}
					}
				}

				add_action( 'admin_notices', [ $this, 'atlt_admin_notices' ], PHP_INT_MAX );
			}

			function atlt_admin_notices() {
				do_action( 'atlt_display_admin_notices' );
			}

			function atlt_display_admin_notices() {
				$ratingDiv = get_option('atlt-pro-ratingDiv', 'no');
				$alreadyRated = get_option('atlt-already-rated', 'no');
	
				// Check if the user has already rated
				if ($ratingDiv !== 'yes' && $alreadyRated !== 'yes' && class_exists('Atlt_Dashboard')) {
					Atlt_Dashboard::review_notice(
						'atlt', 
						'LocoAI – Auto Translate for Loco Translate (Pro)', 
						'https://wordpress.org/support/plugin/automatic-translator-addon-for-loco-translate/reviews/#new-post', 
						ATLT_PRO_URL . '/assets/images/atlt-logo.png'
					);
				}
			}

		/*
		|------------------------------------------------------------------------
		|  Enqueue required JS file
		|------------------------------------------------------------------------
		*/
		function atlt_enqueue_scripts( $hook ) {
			// load assets only on editor page
			if ( $hook == 'loco-translate_page_loco-atlt-register' ) {
				return;
			}
			if (
			( isset( $_REQUEST['action'] ) && $_REQUEST['action'] == 'file-edit' ) ) {
				$key = trim( ProHelpers::getLicenseKey() );
				if ( ProHelpers::validKey( $key ) ) {
					wp_register_script( 'loco-addon-custom', ATLT_PRO_URL . 'assets/js/pro-custom.min.js', array( 'loco-translate-admin' ), ATLT_PRO_VERSION, true );
					wp_register_script( 'atlt-chrome-ai-translator-for-loco', ATLT_PRO_URL . 'assets/js/chrome-ai-translator.min.js', array( 'loco-addon-custom' ), ATLT_PRO_VERSION, true );
				} else {
					wp_register_script( 'loco-addon-custom', ATLT_PRO_URL . 'assets/js/custom.min.js', array( 'loco-translate-admin' ), ATLT_PRO_VERSION, true );
				}

					wp_register_style(
						'loco-addon-custom-css',
						ATLT_PRO_URL . 'assets/css/custom.min.css',
						null,
						ATLT_PRO_VERSION,
						'all'
					);
					// load yandex widget
					wp_register_script( 'atlt-yandex-widget', ATLT_PRO_URL . 'assets/js/widget.js?widgetId=ytWidget&pageLang=en&widgetTheme=light&autoMode=false', array( 'loco-translate-admin' ), ATLT_PRO_VERSION, true );

						wp_enqueue_script( 'loco-addon-custom' );
						wp_enqueue_script( 'atlt-chrome-ai-translator-for-loco' );
						wp_enqueue_script( 'atlt-yandex-widget' );
						wp_enqueue_style( 'loco-addon-custom-css' );

						$key = trim( ProHelpers::getLicenseKey() );
				if ( ProHelpers::validKey( $key ) ) {
					// Enqueue Deepl JS file
					wp_enqueue_script( 'doc_index', 'https://unpkg.com/docx@5.0.2/build/index.js', array( 'jquery' ), ATLT_PRO_VERSION, true );
					wp_enqueue_script( 'filesaver', 'https://cdnjs.cloudflare.com/ajax/libs/FileSaver.js/1.3.8/FileSaver.js', array( 'jquery' ), ATLT_PRO_VERSION, true );
					wp_enqueue_script( 'docxtemplater', 'https://cdnjs.cloudflare.com/ajax/libs/docxtemplater/3.1.9/docxtemplater.js', array( 'jquery' ), ATLT_PRO_VERSION, true );
					wp_enqueue_script( 'jszip', 'https://cdnjs.cloudflare.com/ajax/libs/jszip/2.6.1/jszip.js', array( 'jquery' ), ATLT_PRO_VERSION, true );
				}

				$api_keys = array();
				if (!empty(get_option('LocoAutomaticTranslateAddonPro_google_api_key', ''))) {
					$api_keys[] = 'google';
				}
				if (!empty(get_option('LocoAutomaticTranslateAddonPro_openai_api_key', ''))) {
					$api_keys[] = 'openai';
				}

				$extraData['ajax_url']        = admin_url( 'admin-ajax.php' );
				$extraData['nonce']           = wp_create_nonce( 'loco-addon-nonces' );
				$extraData['ATLT_URL']        = ATLT_PRO_URL;
				$extraData['preloader_path']  = 'preloader.gif';
				$extraData['gt_preview']      = 'google.png';
				$extraData['dpl_preview']     = 'deepl.png';
				$extraData['yt_preview']      = 'yandex.png';
				$extraData['chatGPT_preview'] = 'chatgpt.png';
				$extraData['geminiAI_preview']= 'gemini.png';
				$extraData['chromeAi_preview']      = 'chrome.png';
				$extraData['document_preview'] = 'document.svg';
				$extraData['openai_preview']    = 'openai.png';
				$extraData['error_preview']    = 'error-icon.svg';

				$extraData['extra_class']= is_rtl() ? 'atlt-rtl' : '';
				$extraData['api_key']         = $api_keys;
				$extraData['dashboard_url'] = admin_url('admin.php?page=loco-atlt-dashboard');
				    $extraData['loco_settings_url'] = admin_url( 'admin.php?page=loco-config&action=apis' );

					wp_localize_script( 'loco-addon-custom', 'extradata', $extraData );
					// copy object
					wp_add_inline_script(
						'loco-translate-admin',
						'
            var returnedTarget = JSON.parse(JSON.stringify(window.loco));
            window.locoConf=returnedTarget;'
					);	
			}
		}

		/*
		|------------------------------------------------------
		|    Plugin activation
		|------------------------------------------------------
		*/
		
		/*
		|------------------------------------------------------
		|    Plugin activation
		|------------------------------------------------------
		*/
		public function atlt_activate() {

			update_option('atlt-pro-version', ATLT_PRO_VERSION);
			update_option('atlt-pro-installDate', gmdate('Y-m-d h:i:s'));
			update_option('atlt-type', 'PRO');

			if(!get_option('atlt-pro-install-date')) {
				add_option('atlt-pro-install-date', gmdate('Y-m-d h:i:s'));
			}

			if (!get_option('atlt_pro_initial_save_version')) {
				add_option('atlt_pro_initial_save_version', ATLT_PRO_VERSION);
			}

			$get_opt_in = get_option('atlt_feedback_opt_in');

			if ($get_opt_in =='yes' && !wp_next_scheduled('atlt_extra_data_update')) {

				wp_schedule_event(time(), 'every_30_days', 'atlt_extra_data_update');
			}
			
		}

		
		/*
		|-------------------------------------------------------
		|    Plugin deactivation
		|-------------------------------------------------------
		*/
		public function atlt_deactivate() {
			 wp_clear_scheduled_hook('atlt_extra_data_update');

		}

		/**
		 * Throw error on object clone.
		 *
		 * The whole idea of the singleton design pattern is that there is a single
		 * object therefore, we don't want the object to be cloned.
		 */
		public function __clone() {
			// Cloning instances of the class is forbidden.
			_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'loco-auto-translate' ), '2.3' );
		}

		/**
		 * Disable unserializing of the class.
		 */
		public function __wakeup() {
			// Unserializing instances of the class is forbidden.
			_doing_it_wrong( __FUNCTION__, __( 'Cheatin&#8217; huh?', 'loco-auto-translate' ), '2.3' );
		}

	}

	function ATLT_PRO() {
		return LocoAutoTranslateAddonPro::get_instance();
	}
	ATLT_PRO();

}

