<?php

/**
 * Plugin Name: AnyWareX Clone Translate
 * Plugin URI: https://www.anywarex.com/projects/wordpress/wp-plugins/anywarex-clone-translate/
 * Description: Clone and manage translations of posts and pages.
 * Version: 2.4.1
 * Author: AnyWareX e.U.
 * Author URI: https://www.anywarex.com
 * Text Domain: anywarex-clone-translate
 * Domain Path: /languages
 * License: GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Requires at least: 6.0
 * Tested up to: 6.9
 * Requires PHP: 7.4
 */
defined('ABSPATH') || exit;

// =====================================================================
//  Constants
// =====================================================================

if (!defined('AWXCT_VERSION')) {
	// Read the plugin header version so it only needs to be maintained in one place.
	if (!function_exists('get_file_data')) {
		require_once ABSPATH . 'wp-admin/includes/plugin.php';
	}
	$awxct_version_data = get_file_data(__FILE__, array('Version' => 'Version'), 'plugin');
	define('AWXCT_VERSION', isset($awxct_version_data['Version']) ? $awxct_version_data['Version'] : '0.0.0');
}
// if (!defined('AWXCT_DEBUG')) {
//     define('AWXCT_DEBUG', false);
// }

if (!defined('AWXCT_FILE')) {
	define('AWXCT_FILE', __FILE__);
}
if (!defined('AWXCT_PATH')) {
	define('AWXCT_PATH', plugin_dir_path(__FILE__));
}
if (!defined('AWXCT_URL')) {
	define('AWXCT_URL', plugin_dir_url(__FILE__));
}

// DB table constants.
global $wpdb;

if (!defined('AWXCT_TABLE_LANGUAGES')) {
	define('AWXCT_TABLE_LANGUAGES', $wpdb->prefix . 'awxct_languages');
}
if (!defined('AWXCT_TABLE_TRANSLATIONS')) {
	define('AWXCT_TABLE_TRANSLATIONS', $wpdb->prefix . 'awxct_translations');
}

// =====================================================================
//  Add-on hooks (Free stays independent)
// =====================================================================

if (!function_exists('awxct_is_plus_unlocked')) {
	/**
	 * Allow add-on plugins (Plus/Pro) to unlock premium features.
	 *
	 * Free version default: locked (false).
	 *
	 * @return bool True if an add-on declares an unlocked state.
	 */
	function awxct_is_plus_unlocked(): bool
	{
		return (bool) apply_filters('awxct_is_plus_unlocked', false);
	}
}

// =====================================================================
//  Core includes
// =====================================================================


// Public API fallbacks (prevents fatal errors when Plus/Pro are not active).
require_once AWXCT_PATH . 'includes/public-api.php';

require_once AWXCT_PATH . 'includes/helpers.php';
require_once AWXCT_PATH . 'includes/class-language.php';
require_once AWXCT_PATH . 'includes/class-languages.php';
require_once AWXCT_PATH . 'includes/class-mapping.php';
require_once AWXCT_PATH . 'includes/class-frontend.php';
require_once AWXCT_PATH . 'includes/class-clone.php';
require_once AWXCT_PATH . 'includes/languages-data.php';
require_once AWXCT_PATH . 'includes/handle-set-active.php';
require_once AWXCT_PATH . 'includes/class-routing.php';

// License & feature flags.
require_once AWXCT_PATH . 'includes/class-features.php';
require_once AWXCT_PATH . 'includes/helpers-langs.php';

// Dictionary helpers.

// Payment + license issuing is handled externally (license shop).
require_once AWXCT_PATH . 'includes/class-seo-meta.php';

if ( class_exists( 'AWXCT_Frontend' ) && ! class_exists( 'AWX_PLG_CT_Frontend' ) ) {
	class_alias( 'AWXCT_Frontend', 'AWX_PLG_CT_Frontend' );
}

// Allow add-ons to load after core is ready.
do_action('awxct_loaded');

// =====================================================================
//  Admin-only includes
// =====================================================================

if (is_admin()) {
	require_once AWXCT_PATH . 'admin/class-admin-menu.php';
	require_once AWXCT_PATH . 'admin/class-admin-metabox.php';
	require_once AWXCT_PATH . 'admin/handlers/languages-save.php';
	require_once AWXCT_PATH . 'admin/handlers/mapping-save.php';

	new AWXCT_Clone_Translate_Admin_Menu();
	new AWXCT_Clone_Translate_Admin_Metabox();
	new AWXCT_Clone_Translate_Clone();

	// Allow add-ons to register admin pages/handlers.
	do_action('awxct_admin_loaded');

	add_action('admin_post_awxct_language_add', 'awxct_handle_language_add');
	add_action('admin_post_awxct_languages_save', 'awxct_handle_languages_save');
	add_action('admin_post_awxct_language_delete', 'awxct_handle_language_delete');
}

// =====================================================================
//  Activation
// =====================================================================

register_activation_hook(__FILE__, 'awxct_activate');

/**
 * Plugin activation callback.
 *
 * Creates required tables and seeds language data.
 *
 * @return void
 */
function awxct_activate()
{
	global $wpdb;

	require_once ABSPATH . 'wp-admin/includes/upgrade.php';

	$charset_collate = $wpdb->get_charset_collate();

	// Languages table.
	$sql_languages = 'CREATE TABLE IF NOT EXISTS `' . AWXCT_TABLE_LANGUAGES . "` (
		id INT AUTO_INCREMENT,
		code VARCHAR(20) NOT NULL,
		english_name VARCHAR(100) NOT NULL,
		native_name VARCHAR(100) NOT NULL,
		active TINYINT(1) DEFAULT 0,
		is_default TINYINT(1) DEFAULT 0,
		PRIMARY KEY (id),
		UNIQUE (code)
	) $charset_collate;";

	// Translations table.
	$sql_translations = 'CREATE TABLE IF NOT EXISTS `' . AWXCT_TABLE_TRANSLATIONS . "` (
		id INT AUTO_INCREMENT,
		root_post_id BIGINT(20) NOT NULL,
		original_post_id BIGINT(20) NOT NULL,
		translated_post_id BIGINT(20) NOT NULL,
		language_code VARCHAR(20) NOT NULL,
		is_active TINYINT(1) DEFAULT 1,
		PRIMARY KEY (id),
		UNIQUE (translated_post_id)
	) $charset_collate;";

	dbDelta($sql_languages);
	dbDelta($sql_translations);

	// Optional: seed languages (moved out of main file).
	// If you still want seeding, do it in a dedicated class/file and call it here.
	if (function_exists('awxct_seed_languages')) {
		awxct_seed_languages();
	}
}

update_option('awxct_version', AWXCT_VERSION);

// =====================================================================
//  Deactivation / Uninstall
// =====================================================================

register_deactivation_hook(
	__FILE__,
	function () {
		if (class_exists('AWXCT_License')) {
			AWXCT_License::clear_cron();
		}
	}
);

// Uninstall (placeholder – in case you later want to remove tables/options).
if (!function_exists('awxct_uninstall')) {
	/**
	 * Placeholder uninstall callback.
	 *
	 * @return void
	 */
	function awxct_uninstall() {}
}
register_uninstall_hook(__FILE__, 'awxct_uninstall');

// =====================================================================
//  Housekeeping: clean up mapping when a post is permanently deleted
// =====================================================================

if (!function_exists('awxct_cleanup_mapping_on_delete')) {
	/**
	 * Removes all mapping entries that reference this post.
	 * Runs only in the admin (emptying trash / "Delete permanently").
	 *
	 * @param int $post_id Post ID.
	 * @return void
	 */
	function awxct_cleanup_mapping_on_delete($post_id)
	{
		if (!is_admin()) {
			return;
		}
		if (!class_exists('AWXCT_Clone_Translate_Mapping')) {
			return;
		}

		$mapping = new AWXCT_Clone_Translate_Mapping();
		if (method_exists($mapping, 'delete_by_post')) {
			$mapping->delete_by_post($post_id);
		}
	}
}
add_action('before_delete_post', 'awxct_cleanup_mapping_on_delete');

// =====================================================================
//  Mapping: "Remove from translations" (Mapping page -> admin-post.php)
// =====================================================================

if (!function_exists('awxct_handle_unlink_translation')) {
	/**
	 * Handle "Remove from translations" action from the mapping page.
	 *
	 * @return void
	 */
	function awxct_handle_unlink_translation()
	{
		// Accept both POST and GET (admin-post.php works with either).
		// Verify nonce first to ensure input origin is validated before processing any request data.
		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_die( esc_html__( 'You are not allowed to do this.', 'anywarex-clone-translate' ) );
		}

		check_admin_referer( 'awxct_unlink_translation', 'awxct_unlink_nonce' );

		$post_id = isset( $_REQUEST['post_id'] ) ? absint( wp_unslash( $_REQUEST['post_id'] ) ) : 0;

if (!$post_id) {
			wp_die(esc_html__('Missing post_id.', 'anywarex-clone-translate'));
		}

		if (!current_user_can('edit_post', $post_id)) {
			wp_die(esc_html__('You are not allowed to do this.', 'anywarex-clone-translate'));
		}

		$nonce = isset($_REQUEST['awxct_unlink_nonce'])
			? sanitize_text_field(wp_unslash($_REQUEST['awxct_unlink_nonce']))
			: '';

		if (!$nonce || !wp_verify_nonce( $nonce, 'awxct_unlink_translation' )) {
			wp_die(esc_html__('Security check failed.', 'anywarex-clone-translate'));
		}

		// Use central Mapping class so we delete all relations for this post.
		if (class_exists('AWXCT_Clone_Translate_Mapping')) {
			$mapping = new AWXCT_Clone_Translate_Mapping();

			if (method_exists($mapping, 'delete_by_post')) {
				$mapping->delete_by_post($post_id);
			}
		}

		// Also remove language meta from the post (same as metabox AJAX handler).
		delete_post_meta($post_id, '_awxct_translate_lang');

		// Redirect back to the mapping page with a notice.
		$redirect = wp_get_referer();
		if (!$redirect) {
			$redirect = admin_url('admin.php?page=anywarex-clone-translate-mapping');
		}
		$redirect = add_query_arg('awxmsg', 'unlinked', $redirect);

		wp_safe_redirect($redirect);
		exit;
	}
}
add_action('admin_post_awxct_unlink_translation', 'awxct_handle_unlink_translation');

// =====================================================================
//  Plugin action links / meta links
// =====================================================================

add_filter(
	'plugin_action_links_' . plugin_basename(__FILE__),
	function ($links) {
		$url = admin_url('admin.php?page=anywarex-clone-translate');
		array_unshift(
			$links,
			'<a href="' . esc_url($url) . '">' . esc_html__('Einstellungen', 'anywarex-clone-translate') . '</a>'
		);
		return $links;
	}
);

add_filter(
	'plugin_row_meta',
	function ($links, $file) {
		if ($file !== plugin_basename(__FILE__)) {
			return $links;
		}
		$links[] = '<a href="' . esc_url('https://www.anywarex.com') . '" target="_blank" rel="noopener">'
			. esc_html__('Docs', 'anywarex-clone-translate')
			. '</a>';
		return $links;
	},
	10,
	2
);

/* =========================================================
 * Plus / Pro Unlock Hooks (Free is source of truth)
 * ========================================================= */

/**
 * Check whether Plus features are unlocked.
 *
 * Plus/Pro add-ons may call this helper. Free decides via filters/options.
 *
 * @return bool
 */
function awxct_is_plus_unlocked() {
	return (bool) apply_filters( 'awxct_is_plus_unlocked', false );
}

/**
 * Check whether Pro features are unlocked.
 *
 * Plus/Pro add-ons may call this helper. Free decides via filters/options.
 *
 * @return bool
 */
function awxct_is_pro_unlocked() {
	return (bool) apply_filters( 'awxct_is_pro_unlocked', false );
}

/**
 * Resolve current plan from options (strict tiers).
 *
 * Tries:
 * 1) awxct_license_plan (explicit)
 * 2) awxct option array (legacy license storage)
 * 3) site options (multisite)
 *
 * @return string 'plus'|'pro'|''
 */
function awxct_resolve_license_plan() {
	$plan = '';

	$opt = get_option( 'awxct_license_plan', '' );
	if ( is_string( $opt ) && '' !== $opt ) {
		$plan = $opt;
	}

	if ( '' === $plan ) {
		$lic = get_option( 'awxct', array() );
		if ( is_array( $lic ) ) {
			foreach ( array( 'plan', 'edition', 'tier', 'license_plan' ) as $k ) {
				if ( isset( $lic[ $k ] ) && is_string( $lic[ $k ] ) && '' !== $lic[ $k ] ) {
					$plan = $lic[ $k ];
					break;
				}
			}
		}
	}

	if ( '' === $plan && function_exists( 'get_site_option' ) ) {
		$opt = get_site_option( 'awxct_license_plan', '' );
		if ( is_string( $opt ) && '' !== $opt ) {
			$plan = $opt;
		} else {
			$lic = get_site_option( 'awxct', array() );
			if ( is_array( $lic ) ) {
				foreach ( array( 'plan', 'edition', 'tier', 'license_plan' ) as $k ) {
					if ( isset( $lic[ $k ] ) && is_string( $lic[ $k ] ) && '' !== $lic[ $k ] ) {
						$plan = $lic[ $k ];
						break;
					}
				}
			}
		}
	}

	$plan = strtolower( trim( (string) $plan ) );

	if ( 'plus' === $plan || 'pro' === $plan ) {
		return $plan;
	}
	if ( false !== strpos( $plan, 'pro' ) ) {
		return 'pro';
	}
	if ( false !== strpos( $plan, 'plus' ) ) {
		return 'plus';
	}
	return '';
}

/**
 * Default plan resolution (STRICT TIERS).
 *
 * Note: Pro does NOT fall back to Plus.
 */
add_filter( 'awxct_is_plus_unlocked', function( $default ) {
	return ( awxct_resolve_license_plan() === 'plus' );
} );

add_filter( 'awxct_is_pro_unlocked', function( $default ) {
	return ( awxct_resolve_license_plan() === 'pro' );
} );
