<?php
/**
 * Migration Manager
 *
 * Orchestrates the migration process: detects active SEO plugins,
 * runs batch imports via AJAX, tracks progress, and handles cleanup.
 *
 * @package SEOvaultSEO\Migration
 */

namespace SEOvaultSEO\Migration;

use SEOvaultSEO\Utils\Logger;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

class MigrationManager {

	const BATCH_SIZE = 50;

	private static $instance = null;

	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	private function __construct() {}

	public static function init() {
		add_action( 'wp_ajax_seovaultseo_migration_import', array( __CLASS__, 'ajax_import_batch' ) );
		add_action( 'wp_ajax_seovaultseo_migration_status', array( __CLASS__, 'ajax_get_status' ) );
		add_action( 'wp_ajax_seovaultseo_migration_cleanup', array( __CLASS__, 'ajax_cleanup' ) );
	}

	/**
	 * Get available importers for active SEO plugins.
	 *
	 * @return array Map of slug => importer instance.
	 */
	public static function get_available_importers() {
		$available = array();
		$plugins   = ImporterUtils::get_seo_plugins_list();

		foreach ( $plugins as $file => $info ) {
			if ( ! class_exists( $info['class'] ) ) {
				continue;
			}
			$instance = new $info['class']();
			if ( $instance->is_plugin_active() ) {
				$slug               = dirname( $file );
				$available[ $slug ] = $instance;
			}
		}

		return $available;
	}

	/**
	 * Get migration status for a provider.
	 *
	 * @param string $provider_slug Provider slug.
	 * @return array
	 */
	public static function get_status( $provider_slug = null ) {
		$importers = self::get_available_importers();

		if ( empty( $importers ) ) {
			return array(
				'available' => false,
				'providers' => array(),
				'message'   => __( 'No supported SEO plugins detected for migration.', 'seovault-ai' ),
			);
		}

		$providers   = array();
		$post_types  = get_post_types( array( 'public' => true ), 'names' );
		$taxonomies  = array_keys( ImporterUtils::get_public_taxonomies() );
		$tax_objects = ImporterUtils::get_public_taxonomies();

		foreach ( $importers as $slug => $importer ) {
			if ( null !== $provider_slug && $slug !== $provider_slug ) {
				continue;
			}

			$post_data = $importer->get_count_and_posts( $post_types, 0, 0 );
			$term_data = $importer->get_count_and_terms( $taxonomies, $tax_objects, 0, 0 );

			$providers[ $slug ] = array(
				'name'        => $importer->get_plugin_name(),
				'file'        => $importer->get_plugin_file(),
				'post_total'  => $post_data['total_items'],
				'term_total'  => $term_data['total_items'],
				'total_items' => $post_data['total_items'] + $term_data['total_items'],
			);
		}

		return array(
			'available' => true,
			'providers' => $providers,
		);
	}

	/**
	 * Import a batch of posts.
	 *
	 * @param string $provider_slug Provider slug.
	 * @param int    $offset        Offset.
	 * @param string $type          'posts' or 'terms'.
	 * @return array
	 */
	public static function import_batch( $provider_slug, $offset, $type = 'posts' ) {
		$importers = self::get_available_importers();
		if ( ! isset( $importers[ $provider_slug ] ) ) {
			return array(
				'success' => false,
				'message' => __( 'Provider not found or not active.', 'seovault-ai' ),
			);
		}

		$importer    = $importers[ $provider_slug ];
		$post_types  = get_post_types( array( 'public' => true ), 'names' );
		$taxonomies  = array_keys( ImporterUtils::get_public_taxonomies() );
		$tax_objects = ImporterUtils::get_public_taxonomies();

		if ( 'global' === $type ) {
			$result = $importer->import_global_settings();
			return array(
				'success'  => $result['success'],
				'message'  => $result['message'],
				'imported' => $result['success'] ? 1 : 0,
				'failed'   => $result['success'] ? 0 : 1,
				'offset'   => 0,
				'total'    => 1,
				'has_more' => false,
				'done'     => true,
				'log'      => array( $result['message'] ),
			);
		}

		$query_offset = 0;
		if ( 'posts' === $type ) {
			$data  = $importer->get_count_and_posts( $post_types, self::BATCH_SIZE, $query_offset );
			$ids   = $data['post_ids'];
			$total = $data['total_items'];
		} else {
			$data  = $importer->get_count_and_terms( $taxonomies, $tax_objects, self::BATCH_SIZE, $query_offset );
			$ids   = $data['term_ids'];
			$total = $data['total_items'];
		}

		if ( empty( $ids ) ) {
			return array(
				'success'  => true,
				'message'  => __( 'No items found to import.', 'seovault-ai' ),
				'imported' => 0,
				'failed'   => 0,
				'offset'   => $offset,
				'total'    => $total,
				'has_more' => false,
				'done'     => true,
			);
		}

		$imported = 0;
		$failed   = 0;
		$log      = array();

		foreach ( $ids as $id ) {
			if ( 'posts' === $type ) {
				$result = $importer->import_post( (int) $id );
			} else {
				$result = $importer->import_term( (int) $id );
			}

			if ( $result['success'] ) {
				++$imported;
				$log[] = '[OK] ' . $result['message'];
			} else {
				++$failed;
				if ( ! empty( $result['no_data_found'] ) ) {
					ImporterUtils::update_migration_flag( (int) $id, 'posts' === $type );
				}
				$log[] = '[SKIP] ' . $result['message'];
			}
		}

		$processed_count = count( $ids );
		$new_offset      = $offset + $processed_count;
		$display_total   = $offset + $total;
		$has_more        = $processed_count < $total;

		return array(
			'success'  => true,
			'message'  => sprintf(
				/* translators: 1: imported count, 2: total */
				__( 'Imported %1$d of %2$d items.', 'seovault-ai' ),
				$imported,
				count( $ids )
			),
			'imported' => $imported,
			'failed'   => $failed,
			'offset'   => $new_offset,
			'total'    => $display_total,
			'has_more' => $has_more,
			'done'     => ! $has_more,
			'log'      => $log,
		);
	}

	/**
	 * AJAX handler for batch import.
	 */
	public static function ajax_import_batch() {
		check_ajax_referer( 'seovaultseo_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			Logger::error( 'AJAX migration_import: capability check failed' );
			wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'seovault-ai' ) ), 403 );
		}

		$provider = isset( $_POST['provider'] ) ? sanitize_text_field( wp_unslash( $_POST['provider'] ) ) : '';
		$offset   = isset( $_POST['offset'] ) ? absint( $_POST['offset'] ) : 0;
		$type     = isset( $_POST['type'] ) ? sanitize_text_field( wp_unslash( $_POST['type'] ) ) : 'posts';

		if ( empty( $provider ) ) {
			Logger::error( 'AJAX migration_import: provider not specified' );
			wp_send_json_error( array( 'message' => __( 'Provider not specified.', 'seovault-ai' ) ) );
		}

		Logger::log(
			'AJAX migration_import: inputs',
			array(
				'provider' => $provider,
				'offset'   => $offset,
				'type'     => $type,
			)
		);

		$result = self::import_batch( $provider, $offset, $type );
		Logger::log(
			'AJAX migration_import: result',
			array(
				'provider' => $provider,
				'imported' => $result['imported'] ?? 0,
				'failed'   => $result['failed'] ?? 0,
				'has_more' => $result['has_more'] ?? false,
			)
		);
		wp_send_json_success( $result );
	}

	/**
	 * AJAX handler for status.
	 */
	public static function ajax_get_status() {
		check_ajax_referer( 'seovaultseo_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			Logger::error( 'AJAX migration_status: capability check failed' );
			wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'seovault-ai' ) ), 403 );
		}

		Logger::log( 'AJAX migration_status: entered' );
		$status = self::get_status();
		Logger::log(
			'AJAX migration_status: success',
			array(
				'available'      => $status['available'] ?? false,
				'provider_count' => count( $status['providers'] ?? array() ),
			)
		);
		wp_send_json_success( $status );
	}

	/**
	 * AJAX handler for cleanup.
	 */
	public static function ajax_cleanup() {
		check_ajax_referer( 'seovaultseo_admin', 'nonce' );

		if ( ! current_user_can( 'manage_options' ) ) {
			Logger::error( 'AJAX migration_cleanup: capability check failed' );
			wp_send_json_error( array( 'message' => __( 'Unauthorized.', 'seovault-ai' ) ), 403 );
		}

		$provider = isset( $_POST['provider'] ) ? sanitize_text_field( wp_unslash( $_POST['provider'] ) ) : '';
		if ( empty( $provider ) ) {
			Logger::error( 'AJAX migration_cleanup: provider not specified' );
			wp_send_json_error( array( 'message' => __( 'Provider not specified.', 'seovault-ai' ) ) );
		}

		$importers = self::get_available_importers();
		if ( ! isset( $importers[ $provider ] ) ) {
			Logger::error( 'AJAX migration_cleanup: provider not found', array( 'provider' => $provider ) );
			wp_send_json_error( array( 'message' => __( 'Provider not found.', 'seovault-ai' ) ) );
		}

		Logger::log( 'AJAX migration_cleanup: running', array( 'provider' => $provider ) );
		$result = $importers[ $provider ]->cleanup();
		Logger::log( 'AJAX migration_cleanup: success', array( 'provider' => $provider ) );
		wp_send_json_success( $result );
	}

	/**
	 * Import global settings from a provider.
	 *
	 * @param string $provider_slug Provider slug.
	 * @return array
	 */
	public static function import_global( $provider_slug ) {
		$importers = self::get_available_importers();
		if ( ! isset( $importers[ $provider_slug ] ) ) {
			return array(
				'success' => false,
				'message' => __( 'Provider not found or not active.', 'seovault-ai' ),
			);
		}

		return $importers[ $provider_slug ]->import_global_settings();
	}
}
