<?php
/**
 * Thumbnail size detection and management.
 *
 * @package CoffeeWP_Media_Cleanup
 */

namespace CWPM\Thumbnail;

use CWPM\Source\Detector;

defined( 'ABSPATH' ) || exit;

class Sizes {

	/**
	 * Register hooks that filter thumbnail generation.
	 */
	public static function register_hooks() {
		add_filter( 'intermediate_image_sizes_advanced', array( __CLASS__, 'filter_sizes' ) );
	}

	/**
	 * Remove disabled sizes so WordPress won't generate them.
	 *
	 * @param array $sizes Associative array of size data.
	 * @return array Filtered sizes.
	 */
	public static function filter_sizes( $sizes ) {
		$disabled = self::get_disabled();
		foreach ( $disabled as $name ) {
			unset( $sizes[ $name ] );
		}
		return $sizes;
	}

	/**
	 * Get all registered image sizes with metadata.
	 *
	 * @return array Associative array keyed by size name. Each entry contains:
	 *               - width  (int)
	 *               - height (int)
	 *               - crop   (bool)
	 *               - source (string) 'core' | 'theme' | 'plugin'
	 *               - enabled (bool)
	 */
	public static function get_all() {
		$registered = wp_get_registered_image_subsizes();
		$disabled   = self::get_disabled();
		$sources    = Detector::detect( $registered );
		$sizes      = array();

		foreach ( $registered as $name => $data ) {
			$source_info    = isset( $sources[ $name ] ) ? $sources[ $name ] : array(
				'type' => 'unknown',
				'name' => '',
			);
			$sizes[ $name ] = array(
				'width'       => (int) $data['width'],
				'height'      => (int) $data['height'],
				'crop'        => (bool) $data['crop'],
				'source'      => $source_info['type'],
				'source_name' => $source_info['name'],
				'enabled'     => ! in_array( $name, $disabled, true ),
			);
		}

		uksort( $sizes, array( __CLASS__, 'sort_sizes' ) );

		return $sizes;
	}

	/**
	 * Get the list of disabled size names.
	 *
	 * @return array
	 */
	public static function get_disabled() {
		$option = get_option( 'cwpm_disabled_sizes', array() );
		return is_array( $option ) ? $option : array();
	}

	/**
	 * Save the list of disabled size names.
	 *
	 * @param array $disabled Array of size name strings.
	 * @return bool
	 */
	public static function save_disabled( $disabled ) {
		$disabled = array_map( 'sanitize_text_field', $disabled );
		return update_option( 'cwpm_disabled_sizes', $disabled );
	}

	/**
	 * Get WP core size names dynamically.
	 *
	 * Sizes absent from $_wp_additional_image_sizes were not registered via
	 * add_image_size() and are therefore WordPress built-ins. This works for
	 * any WP version without a hardcoded list.
	 *
	 * @return string[]
	 */
	public static function get_core_sizes() {
		global $_wp_additional_image_sizes;

		$registered = wp_get_registered_image_subsizes();
		$additional = is_array( $_wp_additional_image_sizes ) ? $_wp_additional_image_sizes : array();
		$core       = array();

		foreach ( array_keys( $registered ) as $name ) {
			if ( ! isset( $additional[ $name ] ) ) {
				$core[] = $name;
			}
		}

		return $core;
	}

	/**
	 * Sort callback: core sizes first, then alphabetical within each group.
	 *
	 * @param string $a Size name.
	 * @param string $b Size name.
	 * @return int
	 */
	private static function sort_sizes( $a, $b ) {
		$core_sizes = self::get_core_sizes();
		$a_core     = in_array( $a, $core_sizes, true );
		$b_core     = in_array( $b, $core_sizes, true );

		if ( $a_core && ! $b_core ) {
			return -1;
		}
		if ( ! $a_core && $b_core ) {
			return 1;
		}

		return strcasecmp( $a, $b );
	}

	/**
	 * Format a human-readable label for a size name.
	 *
	 * @param string $name Raw size name (e.g. 'medium_large').
	 * @return string Formatted name (e.g. 'Medium Large').
	 */
	public static function format_name( $name ) {
		return ucwords( str_replace( array( '-', '_' ), ' ', $name ) );
	}

	/**
	 * Format dimensions string.
	 *
	 * @param int $width  Width in pixels.
	 * @param int $height Height in pixels.
	 * @return string e.g. "300 × 200" or "768 × auto".
	 */
	public static function format_dimensions( $width, $height ) {
		$w = $width ? $width : 'auto';
		$h = $height ? $height : 'auto';
		return $w . ' &times; ' . $h;
	}
}
