<?php
/**
 * Business logic service for Cache management
 *
 * Provides unified cache control for all schema operations.
 * This is a wrapper around BW_Schema_Cache to provide a consistent interface
 * for the new services layer.
 *
 * @package BW_Schema
 * @since 3.0.0-babel
 */

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

class BW_Schema_Service_Cache {

	/**
	 * Prefix for all options (will be bw_schema_* in v3.0.0+)
	 * For now, keeps backward compatibility with bw_schema_*
	 *
	 * @var string
	 */
	const PREFIX = 'bw_schema_';

	/**
	 * Check if caching is enabled
	 *
	 * @return bool True if schema caching is enabled
	 */
	public static function is_enabled() {
		return get_option( self::PREFIX . 'enable_cache', 'yes' ) === 'yes';
	}

	/**
	 * Enable or disable caching
	 *
	 * @param bool $enabled True to enable caching
	 * @return bool Success
	 */
	public static function set_enabled( $enabled ) {
		update_option( self::PREFIX . 'enable_cache', $enabled ? 'yes' : 'no' );
		return true;
	}

	/**
	 * Clear all schema caches
	 *
	 * Clears transients and any other cached schema data.
	 *
	 * @return array|WP_Error Success array or WP_Error
	 */
	public static function clear_all() {
		if ( class_exists( 'BW_Schema_Cache' ) ) {
			BW_Schema_Cache::clear_all();
		}

		return array( 'success' => true );
	}

	/**
	 * Clear cache for a specific post
	 *
	 * @param int $post_id Post ID
	 * @return bool Success
	 */
	public static function clear_post( $post_id ) {
		if ( class_exists( 'BW_Schema_Cache' ) ) {
			BW_Schema_Cache::clear( $post_id );
		}

		return true;
	}

	/**
	 * Clear organization cache
	 *
	 * Used when organization settings change.
	 *
	 * @return bool Success
	 */
	public static function clear_organization() {
		self::clear_all();
		return true;
	}

	/**
	 * Get cache status
	 *
	 * Returns information about the current cache state (size, enabled, etc).
	 *
	 * @return array Cache status information
	 */
	public static function get_status() {
		$transient_key = self::PREFIX . '%';

		global $wpdb;

		// Count cached items
		$count = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT COUNT(*) FROM $wpdb->options WHERE option_name LIKE %s",
				$transient_key
			)
		);

		return array(
			'enabled'   => self::is_enabled(),
			'count'     => (int) $count,
			'last_clear' => get_option( self::PREFIX . 'cache_last_clear', '' ),
		);
	}

	/**
	 * Get human-readable cache size estimate
	 *
	 * @return string Cache size (e.g., "1.2 MB")
	 */
	public static function get_size_display() {
		global $wpdb;

		$size = $wpdb->get_var(
			$wpdb->prepare(
				"SELECT SUM(CHAR_LENGTH(option_value)) FROM $wpdb->options WHERE option_name LIKE %s",
				self::PREFIX . '%'
			)
		);

		if ( ! $size ) {
			return '0 KB';
		}

		$size = (int) $size;

		if ( $size < 1024 ) {
			return $size . ' B';
		} elseif ( $size < 1024 * 1024 ) {
			return round( $size / 1024, 2 ) . ' KB';
		} else {
			return round( $size / ( 1024 * 1024 ), 2 ) . ' MB';
		}
	}

	/**
	 * Mark cache as just cleared
	 *
	 * Updates the timestamp when cache was last cleared.
	 *
	 * @return void
	 */
	public static function mark_cleared() {
		update_option( self::PREFIX . 'cache_last_clear', current_time( 'mysql' ) );
	}

	/**
	 * Get cache health status
	 *
	 * Returns diagnostic information about cache performance.
	 *
	 * @return array Health status
	 */
	public static function get_health() {
		$status = self::get_status();

		$health = array(
			'is_enabled'  => $status['enabled'],
			'cache_count' => $status['count'],
			'cache_size'  => self::get_size_display(),
			'last_clear'  => $status['last_clear'],
			'issues'      => array(),
		);

		// Check for issues
		if ( ! $health['is_enabled'] ) {
			$health['issues'][] = __( 'Schema caching is disabled. Enable it for better performance.', 'bw-schema' );
		}

		if ( $health['cache_count'] > 10000 ) {
			$health['issues'][] = __( 'Cache is very large. Consider clearing it.', 'bw-schema' );
		}

		return $health;
	}

	/**
	 * Invalidate all related caches when settings change
	 *
	 * Called by service save methods when settings change.
	 *
	 * @return void
	 */
	public static function invalidate_all() {
		self::clear_all();
		self::mark_cleared();
	}
}
