<?php
/**
 * AJAX Handler
 *
 * @package Post_Export_Import_With_Media
 * @since 1.1.0
 */

// Prevent direct access
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * AJAX Handler Class - Manages all AJAX requests
 */
class PEIWM_Ajax_Handler {

	/**
	 * Instance
	 *
	 * @var PEIWM_Ajax_Handler|null
	 */
	private static $instance = null;

	/**
	 * Get instance
	 *
	 * @return PEIWM_Ajax_Handler
	 */
	public static function get_instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 * Constructor
	 */
	private function __construct() {
		$this->init_ajax_hooks();
	}

	/**
	 * Initialize AJAX hooks
	 */
	private function init_ajax_hooks() {
		// System test
		add_action( 'wp_ajax_peiwm_test_config', array( $this, 'ajax_test_config' ) );
		
		// Media stats
		add_action( 'wp_ajax_peiwm_get_media_stats', array( $this, 'ajax_get_media_stats' ) );
		
		// Content stats for batch settings
		add_action( 'wp_ajax_peiwm_get_content_stats', array( $this, 'ajax_get_content_stats' ) );
		
		// Download handlers
		add_action( 'admin_post_peiwm_export_posts_download', array( $this, 'download_export_posts' ) );
		add_action( 'admin_post_peiwm_export_media_download', array( $this, 'download_export_media' ) );
		add_action( 'admin_post_peiwm_download_users_export', array( $this, 'download_export_users' ) );
	}

	/**
	 * AJAX: Test system configuration
	 */
	public function ajax_test_config() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'peiwm_secure_nonce' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'post-export-import-with-media' ) ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Permission denied', 'post-export-import-with-media' ) ) );
		}

		try {
			$upload_dir = wp_upload_dir();
			
			$config = array(
				'php_version' => phpversion(),
				'wordpress_version' => get_bloginfo( 'version' ),
				'upload_max_filesize' => ini_get( 'upload_max_filesize' ),
				'post_max_size' => ini_get( 'post_max_size' ),
				'max_input_time' => ini_get( 'max_input_time' ),
				'max_file_uploads' => ini_get( 'max_file_uploads' ),
				'max_execution_time' => ini_get( 'max_execution_time' ),
				'memory_limit' => ini_get( 'memory_limit' ),
				'current_memory_usage' => memory_get_usage(),
				'peak_memory_usage' => memory_get_peak_usage(),
				'ziparchive_available' => class_exists( 'ZipArchive' ),
				'upload_dir_writable' => is_writable( $upload_dir['basedir'] ),
			);

			wp_send_json_success( $config );

		} catch ( Exception $e ) {
			wp_send_json_error( array( 'message' => esc_html__( 'System test failed', 'post-export-import-with-media' ) ) );
		}
	}

	/**
	 * AJAX: Get content statistics for batch settings
	 */
	public function ajax_get_content_stats() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'peiwm_secure_nonce' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'post-export-import-with-media' ) ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Permission denied', 'post-export-import-with-media' ) ) );
		}

		try {
			$total_posts = wp_count_posts( 'post' );
			$total_pages = wp_count_posts( 'page' );
			$total_media = wp_count_posts( 'attachment' );

			wp_send_json_success( array(
				'total_posts' => $total_posts->publish + $total_posts->draft + $total_posts->pending,
				'total_pages' => $total_pages->publish + $total_pages->draft + $total_pages->pending,
				'total_media' => $total_media->inherit,
			) );

		} catch ( Exception $e ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Failed to get content statistics', 'post-export-import-with-media' ) ) );
		}
	}

	/**
	 * AJAX: Get media statistics - memory efficient using IDs only
	 */
	public function ajax_get_media_stats() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'peiwm_secure_nonce' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Security check failed', 'post-export-import-with-media' ) ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Permission denied', 'post-export-import-with-media' ) ) );
		}

		try {
			@ini_set( 'memory_limit', '512M' );

			// Use wp_count_posts for fast total count - no memory issue
			$counts     = wp_count_posts( 'attachment' );
			$total_files = (int) $counts->inherit;

			// Fetch only IDs to calculate sizes - much less memory than full objects
			$attachment_ids = get_posts( array(
				'post_type'              => 'attachment',
				'numberposts'            => -1,
				'post_status'            => 'inherit',
				'fields'                 => 'ids',
				'no_found_rows'          => true,
				'update_post_meta_cache' => false,
				'update_post_term_cache' => false,
			) );

			$total_size   = 0;
			$file_types   = array();
			$largest_file = array( 'size' => 0, 'name' => '' );

			foreach ( $attachment_ids as $id ) {
				$file_path = get_attached_file( $id );
				$mime_type = get_post_mime_type( $id );
				if ( $file_path && @file_exists( $file_path ) ) {
					$file_size = @filesize( $file_path );
					if ( $file_size === false ) $file_size = 0;
					$total_size += $file_size;

					$mime = sanitize_mime_type( $mime_type );
					$file_types[ $mime ] = ( $file_types[ $mime ] ?? 0 ) + 1;

					if ( $file_size > $largest_file['size'] ) {
						$largest_file = array(
							'size' => $file_size,
							'name' => sanitize_text_field( basename( $file_path ) ),
						);
					}
				}
			}

			arsort( $file_types );

			wp_send_json_success( array(
				'total_files'          => $total_files,
				'total_size'           => $total_size,
				'total_size_formatted' => $this->format_file_size( $total_size ),
				'file_types'           => $file_types,
				'largest_file'         => array(
					'name'           => $largest_file['name'],
					'size'           => $largest_file['size'],
					'size_formatted' => $this->format_file_size( $largest_file['size'] ),
				),
			) );

		} catch ( Exception $e ) {
			wp_send_json_error( array( 'message' => esc_html__( 'Failed to get media statistics', 'post-export-import-with-media' ) ) );
		}
	}

	/**
	 * Download exported posts
	 */
	public function download_export_posts() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'peiwm_download_nonce' ) ) {
			wp_die( esc_html__( 'Security check failed', 'post-export-import-with-media' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied', 'post-export-import-with-media' ) );
		}

		$file_path = isset( $_GET['file'] ) ? sanitize_text_field( wp_unslash( $_GET['file'] ) ) : '';
		
		if ( empty( $file_path ) ) {
			wp_die( esc_html__( 'File not specified', 'post-export-import-with-media' ) );
		}

		$upload_dir = wp_upload_dir();
		$full_path = $upload_dir['basedir'] . '/peiwm-exports/' . basename( $file_path );

		if ( ! file_exists( $full_path ) ) {
			wp_die( esc_html__( 'File not found', 'post-export-import-with-media' ) );
		}

		// Set headers for download
		header( 'Content-Type: application/json' );
		header( 'Content-Disposition: attachment; filename="' . basename( $file_path ) . '"' );
		header( 'Content-Length: ' . filesize( $full_path ) );
		header( 'Cache-Control: no-cache, must-revalidate' );
		header( 'Expires: 0' );

		// Output file
		readfile( $full_path );
		exit;
	}

	/**
	 * Download exported media
	 */
	public function download_export_media() {
		if ( ! isset( $_GET['_wpnonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['_wpnonce'] ) ), 'peiwm_download_nonce' ) ) {
			wp_die( esc_html__( 'Security check failed', 'post-export-import-with-media' ) );
		}

		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied', 'post-export-import-with-media' ) );
		}

		$file_path = isset( $_GET['file'] ) ? sanitize_text_field( wp_unslash( $_GET['file'] ) ) : '';
		
		if ( empty( $file_path ) ) {
			wp_die( esc_html__( 'File not specified', 'post-export-import-with-media' ) );
		}

		$upload_dir = wp_upload_dir();
		$full_path = $upload_dir['basedir'] . '/peiwm-exports/' . basename( $file_path );

		if ( ! file_exists( $full_path ) ) {
			wp_die( esc_html__( 'File not found', 'post-export-import-with-media' ) );
		}

		// Set headers for download
		header( 'Content-Type: application/zip' );
		header( 'Content-Disposition: attachment; filename="' . basename( $file_path ) . '"' );
		header( 'Content-Length: ' . filesize( $full_path ) );
		header( 'Cache-Control: no-cache, must-revalidate' );
		header( 'Expires: 0' );

		// Output file
		readfile( $full_path );
		exit;
	}



	/**
	 * Download exported users JSON
	 */
	public function download_export_users() {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Permission denied', 'post-export-import-with-media' ) );
		}

		$file_path = isset( $_GET['file'] ) ? sanitize_text_field( wp_unslash( $_GET['file'] ) ) : '';

		if ( empty( $file_path ) ) {
			wp_die( esc_html__( 'File not specified', 'post-export-import-with-media' ) );
		}

		$upload_dir = wp_upload_dir();
		$full_path  = $upload_dir['basedir'] . '/peiwm-exports/' . basename( $file_path );

		if ( ! file_exists( $full_path ) ) {
			wp_die( esc_html__( 'File not found', 'post-export-import-with-media' ) );
		}

		header( 'Content-Type: application/json' );
		header( 'Content-Disposition: attachment; filename="' . basename( $file_path ) . '"' );
		header( 'Content-Length: ' . filesize( $full_path ) );
		header( 'Cache-Control: no-cache, must-revalidate' );
		header( 'Expires: 0' );
		readfile( $full_path ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_readfile
		exit;
	}

	/**
	 * Convert size string to bytes
	 *
	 * @param string $size Size string (e.g., '128M', '1G')
	 * @return int Size in bytes
	 */
	private function convert_to_bytes( $size ) {
		$size = trim( $size );
		$last = strtolower( $size[ strlen( $size ) - 1 ] );
		$size = (int) $size;

		switch ( $last ) {
			case 'g':
				$size *= 1024;
			case 'm':
				$size *= 1024;
			case 'k':
				$size *= 1024;
		}

		return $size;
	}

	/**
	 * Get directory size
	 *
	 * @param string $directory Directory path
	 * @return int Size in bytes
	 */
	private function get_directory_size( $directory ) {
		$size = 0;
		
		if ( ! is_dir( $directory ) ) {
			return $size;
		}

		foreach ( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $directory ) ) as $file ) {
			if ( $file->isFile() ) {
				$size += $file->getSize();
			}
		}

		return $size;
	}

	/**
	 * Format file size to human readable
	 *
	 * @param int $bytes File size in bytes
	 * @return string Formatted size
	 */
	private function format_file_size( $bytes ) {
		$units = array( 'B', 'KB', 'MB', 'GB', 'TB' );
		
		for ( $i = 0; $bytes > 1024; $i++ ) {
			$bytes /= 1024;
		}

		return round( $bytes, 2 ) . ' ' . $units[ $i ];
	}
}