<?php

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

/**
 * ADBC General Cleanup Class
 * 
 * This class provides methods for managing general cleanup operations
 */
class ADBC_General_Cleanup {

	/**
	 * Get the general data for all items types or a specific type.
	 *
	 * @param string|null $items_type The type of items to get data for, or null for all types.
	 * 
	 * @return array An array containing the items data, total size, and total count.
	 */
	public static function get_general_data( $items_type = '' ) {

		$keep_last = self::get_keep_last();

		$items = [];
		$total_size = 0;
		$total_count = 0;

		// Determine which handlers to process.
		$types_to_process = $items_type === ''
			? ADBC_Cleanup_Type_Registry::all_handlers()
			: [ $items_type => ADBC_Cleanup_Type_Registry::handler( $items_type ) ];

		foreach ( $types_to_process as $type => $handler ) {

			if ( ! $handler ) {
				continue;
			}

			$count_data = $handler->count();
			$count_data['keep_last'] = $keep_last[ $type ] ?? [];
			// $count_data['url'] = $handler->get_documentation_url();
			// $count_data['has_automation'] = ADBC_Automation::has_automation( $type );

			$items[ $type ] = $count_data;

			$total_size += $count_data['size'];
			$total_count += $count_data['count'];

		}

		return [ 
			'items' => $items,
			'total_size' => $total_size,
			'total_count' => $total_count,
		];

	}

	/**
	 * Get a list of items for a specific type with pagination and filtering.
	 *
	 * @param string $items_type The type of items to retrieve.
	 * 
	 * @param array $args Arguments for pagination and filtering.
	 * 
	 * @return array An array containing the items, total items count, total size, and the real current page.
	 */
	public static function get_items( $items_type, $args ) {

		$handler = ADBC_Cleanup_Type_Registry::handler( $items_type );

		if ( ! $handler ) {
			return [ 
				"items" => [],
				"total_items" => 0,
				"total_size" => 0,
				"real_current_page" => 1,
			];
		}

		$items = $handler->list( $args );
		$total = $handler->count_filtered( $args );

		$total_pages = max( 1, ceil( $total['count'] / $args['items_per_page'] ) );
		$real_current_page = min( $args['current_page'], $total_pages );

		return [ 
			"items" => $items,
			"total_items" => $total['count'],
			"total_size" => $total['size'],
			"real_current_page" => $real_current_page,
		];

	}

	/**
	 * Delete items of a specific type.
	 *
	 * @param string $items_type The type of items to delete.
	 * @param array $items An array of items to delete.
	 * 
	 * @return int The number of items deleted.
	 */
	public static function delete_items( $items_type, $items ) {

		$handler = ADBC_Cleanup_Type_Registry::handler( $items_type );

		if ( ! $handler ) {
			return 0;
		}

		return $handler->delete( $items );

	}

	/**
	 * Purge all items of a specific type.
	 *
	 * @param string $items_type The type of items to purge.
	 * 
	 * @return int The number of items purged.
	 */
	public static function purge_items( $items_type ) {

		$handler = ADBC_Cleanup_Type_Registry::handler( $items_type );

		if ( ! $handler ) {
			return 0;
		}

		return $handler->purge();

	}

	/**
	 * Run cleanup for a specific type of items with a given keep_last config.
	 * Can be called from other services like automation.
	 *
	 * @param string $items_type The type of items to clean up.
	 * @param string $keep_last_config The keep_last config of cleanup ('default', 'no_keep_last', 'custom_keep_last').
	 * @param array $custom_keep_last_value Custom keep last settings if config is 'custom_keep_last'.
	 * 
	 * @return int The number of items purged.
	 */
	public static function run_cleanup( $items_type, $keep_last_config = 'default', $custom_keep_last_value = [] ) {

		$handler = ADBC_Cleanup_Type_Registry::handler( $items_type );

		if ( ! $handler ) {
			return 0;
		}

		switch ( $keep_last_config ) {
			case 'no_keep_last': // Do not keep any items.
				$handler->set_keep_last_config( false );
				break;

			case 'custom_keep_last': // Override the keep_last setting with a custom value.
				$handler->set_keep_last_config( $custom_keep_last_value );
				break;

			default: // 'default' Use the default keep_last setting.
				$handler->set_keep_last_config( null );
		}

		return $handler->purge();

	}

	/**
	 * Set or update the keep_last settings for different items types.
	 *
	 * @param array $new An associative array where keys are items types and values are the keep_last settings.
	 * 
	 * @return array The updated keep_last settings.
	 */
	public static function set_keep_last( $new ) {

		$old = ADBC_Settings::instance()->get_setting( 'keep_last' );

		if ( $old === $new ) {
			return $old;
		}

		// Update old or add new keep_last setting with the given values.
		foreach ( $new as $items_type => $keep_last_setting ) {
			$old[ $items_type ] = $keep_last_setting;
		}

		ADBC_Settings::instance()->update_settings( [ 'keep_last' => $old ] );

		return $old;

	}

	/**
	 * Get the keep_last settings for all items types or a specific type.
	 *
	 * @param string $items_type The type of items to get the keep_last settings for, or an empty string for all types.
	 * 
	 * @return array|false An array of keep_last settings for the specified type, or false if not found.
	 */
	public static function get_keep_last( $items_type = '' ) {

		$keep_last = ADBC_Settings::instance()->get_setting( 'keep_last' );

		if ( $items_type === '' ) {
			return $keep_last;
		}

		if ( isset( $keep_last[ $items_type ] ) ) {
			return $keep_last[ $items_type ];
		}

		return false;

	}

	/**
	 * Delete the keep_last settings for specified items types.
	 *
	 * @param array $items_types An array of items types whose keep_last settings should be deleted.
	 * 
	 * @return array The updated keep_last settings after deletion.
	 */
	public static function delete_keep_last( $items_types ) {

		$old = ADBC_Settings::instance()->get_setting( 'keep_last' );

		foreach ( $items_types as $items_type ) {
			if ( isset( $old[ $items_type ] ) ) {
				unset( $old[ $items_type ] );
			}
		}

		ADBC_Settings::instance()->update_settings( [ 'keep_last' => $old ] );

		return $old;

	}

}
