<?php
/**
 * Helpers for playlist design schema and CSS variable generation.
 *
 * @package TheStudioPlayer
 */

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

/**
 * Get normalized design schema for a playlist and template.
 *
 * @param int    $playlist_id   Playlist post ID.
 * @param string $template_slug Template slug.
 * @return array Normalized design schema.
 */
function thespl_design_get_schema( $playlist_id, $template_slug ) {
	$playlist_id   = (int) $playlist_id;
	$template_slug = is_string( $template_slug ) ? sanitize_key( $template_slug ) : '';
	if ( $playlist_id <= 0 ) {
		return array();
	}

	$design_raw = get_post_meta( $playlist_id, '_thespl_playlist_design', true );
	$design_raw = is_array( $design_raw ) ? $design_raw : array();

	$design = thespl_design_normalize( $design_raw, $template_slug );

	return is_array( $design ) ? $design : array();
}

/**
 * Normalize and fully sanitize raw playlist design input.
 *
 * Accepts raw, unslashed design data from the request and returns a normalized
 * and fully sanitized array suitable for storage in post meta and later use
 * in templates.
 *
 * All string values are sanitized, numeric values are validated and cast,
 * and booleans are normalized to strict bools.
 *
 * @param array  $design_in     Raw design data from the request (after wp_unslash()).
 * @param string $template_slug Active template slug.
 * @return array Normalized and sanitized design settings.
 */
function thespl_design_normalize( $design_in, $template_slug ) {
	$design_in     = is_array( $design_in ) ? $design_in : array();
	$template_slug = is_string( $template_slug ) ? sanitize_key( $template_slug ) : '';

	$defaults              = function_exists( 'thespl_template_get_design_defaults' ) ? thespl_template_get_design_defaults( $template_slug ) : array();
	$accent_default        = isset( $defaults['accent_color'] ) && is_string( $defaults['accent_color'] ) ? sanitize_hex_color( $defaults['accent_color'] ) : '';
	$accent2_default       = isset( $defaults['accent_2_color'] ) && is_string( $defaults['accent_2_color'] ) ? sanitize_hex_color( $defaults['accent_2_color'] ) : '';
	$base_default          = isset( $defaults['base_color'] ) && is_string( $defaults['base_color'] ) ? sanitize_hex_color( $defaults['base_color'] ) : '';
	$text_default          = isset( $defaults['text_color'] ) && is_string( $defaults['text_color'] ) ? sanitize_hex_color( $defaults['text_color'] ) : '';
	$wf_default            = isset( $defaults['waveform_color'] ) && is_string( $defaults['waveform_color'] ) ? sanitize_hex_color( $defaults['waveform_color'] ) : '';
	$ring_default          = isset( $defaults['ring_base_color'] ) && is_string( $defaults['ring_base_color'] ) ? sanitize_hex_color( $defaults['ring_base_color'] ) : '';
	$btn_bg_default        = isset( $defaults['button_bg_color'] ) && is_string( $defaults['button_bg_color'] ) ? sanitize_hex_color( $defaults['button_bg_color'] ) : '';
	$btn_text_default      = isset( $defaults['button_text_color'] ) && is_string( $defaults['button_text_color'] ) ? sanitize_hex_color( $defaults['button_text_color'] ) : '';
	$btn_active_bg_default = isset( $defaults['button_active_bg_color'] ) && is_string( $defaults['button_active_bg_color'] ) ? sanitize_hex_color( $defaults['button_active_bg_color'] ) : '';
	$btn_active_tx_default = isset( $defaults['button_active_text_color'] ) && is_string( $defaults['button_active_text_color'] ) ? sanitize_hex_color( $defaults['button_active_text_color'] ) : '';
	$chip_bg_default       = isset( $defaults['chip_bg_color'] ) && is_string( $defaults['chip_bg_color'] ) ? sanitize_hex_color( $defaults['chip_bg_color'] ) : '';
	$chip_br_default       = isset( $defaults['chip_br_color'] ) && is_string( $defaults['chip_br_color'] ) ? sanitize_hex_color( $defaults['chip_br_color'] ) : '';
	$buffer_alpha_def      = 0.3;
	$buffer_alpha_meta     = isset( $defaults['buffer_ring_alpha'] ) ? $defaults['buffer_ring_alpha'] : null;

	if ( is_numeric( $buffer_alpha_meta ) ) {
		$buffer_alpha_def = (float) $buffer_alpha_meta;
	}
	if ( $buffer_alpha_def < 0 ) {
		$buffer_alpha_def = 0.0;
	} elseif ( $buffer_alpha_def > 1 ) {
		$buffer_alpha_def = 1.0;
	}

	$accent            = isset( $design_in['accent_color'] ) && is_string( $design_in['accent_color'] ) ? sanitize_hex_color( $design_in['accent_color'] ) : $accent_default;
	$accent2           = isset( $design_in['accent_2_color'] ) && is_string( $design_in['accent_2_color'] ) ? sanitize_hex_color( $design_in['accent_2_color'] ) : $accent2_default;
	$base              = isset( $design_in['base_color'] ) && is_string( $design_in['base_color'] ) ? sanitize_hex_color( $design_in['base_color'] ) : $base_default;
	$textcol           = isset( $design_in['text_color'] ) && is_string( $design_in['text_color'] ) ? sanitize_hex_color( $design_in['text_color'] ) : $text_default;
	$waveform          = isset( $design_in['waveform_color'] ) && is_string( $design_in['waveform_color'] ) ? sanitize_hex_color( $design_in['waveform_color'] ) : $wf_default;
	$ringbase          = isset( $design_in['ring_base_color'] ) && is_string( $design_in['ring_base_color'] ) ? sanitize_hex_color( $design_in['ring_base_color'] ) : $ring_default;
	$buffer_alpha_post = isset( $design_in['buffer_ring_alpha'] ) ? $design_in['buffer_ring_alpha'] : null;
	$buffer_alpha      = $buffer_alpha_def;

	if ( is_numeric( $buffer_alpha_post ) ) {
		$buffer_alpha = (float) $buffer_alpha_post;
		if ( $buffer_alpha < 0 ) {
			$buffer_alpha = 0.0;
		} elseif ( $buffer_alpha > 1 ) {
			$buffer_alpha = 1.0;
		}
	}

	$btn_bg          = isset( $design_in['button_bg_color'] ) && is_string( $design_in['button_bg_color'] ) ? sanitize_hex_color( $design_in['button_bg_color'] ) : ( $btn_bg_default ? $btn_bg_default : thespl_mix_hex( $base, $accent, 0.15 ) );
	$btn_text        = isset( $design_in['button_text_color'] ) && is_string( $design_in['button_text_color'] ) ? sanitize_hex_color( $design_in['button_text_color'] ) : ( $btn_text_default ? $btn_text_default : thespl_best_text_on_bg( $btn_bg ) );
	$btn_active_bg   = isset( $design_in['button_active_bg_color'] ) && is_string( $design_in['button_active_bg_color'] ) ? sanitize_hex_color( $design_in['button_active_bg_color'] ) : ( $btn_active_bg_default ? $btn_active_bg_default : $accent );
	$btn_active_text = isset( $design_in['button_active_text_color'] ) && is_string( $design_in['button_active_text_color'] ) ? sanitize_hex_color( $design_in['button_active_text_color'] ) : ( $btn_active_tx_default ? $btn_active_tx_default : thespl_best_text_on_bg( $btn_active_bg ) );
	$chip_bg         = isset( $design_in['chip_bg_color'] ) && is_string( $design_in['chip_bg_color'] ) ? sanitize_hex_color( $design_in['chip_bg_color'] ) : ( $chip_bg_default ? $chip_bg_default : thespl_mix_hex( $base, '#ffffff', 0.06 ) );
	$chip_br         = isset( $design_in['chip_br_color'] ) && is_string( $design_in['chip_br_color'] ) ? sanitize_hex_color( $design_in['chip_br_color'] ) : ( $chip_br_default ? $chip_br_default : thespl_mix_hex( $base, '#ffffff', 0.16 ) );
	$show_pl         = array_key_exists( 'show_playlist', $design_in ) ? (bool) $design_in['show_playlist'] : true;
	$show_info       = array_key_exists( 'show_audio_info', $design_in ) ? (bool) $design_in['show_audio_info'] : false;

	$design = array(
		'accent_color'             => is_string( $accent ) ? $accent : '',
		'accent_2_color'           => is_string( $accent2 ) ? $accent2 : '',
		'base_color'               => is_string( $base ) ? $base : '',
		'text_color'               => is_string( $textcol ) ? $textcol : '',
		'waveform_color'           => is_string( $waveform ) ? $waveform : '',
		'ring_base_color'          => is_string( $ringbase ) ? $ringbase : '',
		'buffer_ring_alpha'        => $buffer_alpha,
		'button_bg_color'          => is_string( $btn_bg ) ? $btn_bg : thespl_mix_hex( $base, $accent, 0.15 ),
		'button_text_color'        => is_string( $btn_text ) ? $btn_text : thespl_best_text_on_bg( $btn_bg ),
		'button_active_bg_color'   => is_string( $btn_active_bg ) ? $btn_active_bg : $accent,
		'button_active_text_color' => is_string( $btn_active_text ) ? $btn_active_text : thespl_best_text_on_bg( $btn_active_bg ),
		'chip_bg_color'            => is_string( $chip_bg ) ? $chip_bg : thespl_mix_hex( $base, '#ffffff', 0.06 ),
		'chip_br_color'            => is_string( $chip_br ) ? $chip_br : thespl_mix_hex( $base, '#ffffff', 0.16 ),
		'show_playlist'            => (bool) $show_pl,
		'show_audio_info'          => (bool) $show_info,
	);

	return $design;
}

/**
 * Build the full design schema for a playlist and template.
 *
 * @param int    $playlist_id   Playlist post ID.
 * @param string $template_slug Template slug.
 *
 * @return array
 */
function thespl_design_get_full_schema( $playlist_id, $template_slug ) {
	$playlist_id   = (int) $playlist_id;
	$template_slug = is_string( $template_slug ) ? sanitize_key( $template_slug ) : '';

	$template_meta = function_exists( 'thespl_template_get_meta' ) ? thespl_template_get_meta( $template_slug ) : array();

	$design = thespl_design_get_schema( $playlist_id, $template_slug );

	$allows_user_css_overrides = true;
	$has_audio_info_panel      = true;

	if ( isset( $template_meta['capabilities']['allows_user_css_overrides'] ) ) {
		$allows_user_css_overrides = (bool) $template_meta['capabilities']['allows_user_css_overrides'];
	} elseif ( function_exists( 'thespl_template_allows_user_css_overrides' ) ) {
		$allows_user_css_overrides = thespl_template_allows_user_css_overrides( $template_slug );
	}

	if ( isset( $template_meta['capabilities']['has_audio_info_panel'] ) ) {
		$has_audio_info_panel = (bool) $template_meta['capabilities']['has_audio_info_panel'];
	} elseif ( function_exists( 'thespl_template_has_audio_info_panel' ) ) {
		$has_audio_info_panel = thespl_template_has_audio_info_panel( $template_slug );
	}

	$show_pl   = ! isset( $design['show_playlist'] ) ? true : (bool) $design['show_playlist'];
	$show_info = ! isset( $design['show_audio_info'] ) ? true : (bool) $design['show_audio_info'];

	if ( ! $allows_user_css_overrides ) {
		if ( function_exists( 'thespl_template_get_show_playlist_pref' ) ) {
			$tpl_playlist_pref = thespl_template_get_show_playlist_pref( $template_slug );
			if ( null !== $tpl_playlist_pref ) {
				$show_pl = (bool) $tpl_playlist_pref;
			}
		}
		if ( function_exists( 'thespl_template_get_show_audio_info_pref' ) ) {
			$tpl_audio_pref = thespl_template_get_show_audio_info_pref( $template_slug );
			if ( null !== $tpl_audio_pref ) {
				$show_info = (bool) $tpl_audio_pref;
			}
		}
	}

	if ( ! $has_audio_info_panel ) {
		$show_info = false;
	}

	$design_initialized_raw      = get_post_meta( $playlist_id, '_thespl_design_initialized', true );
	$design_initialized_meta_set = '' !== $design_initialized_raw;
	$design_initialized          = false;

	$design_raw = get_post_meta( $playlist_id, '_thespl_playlist_design', true );
	$design_raw = is_array( $design_raw ) ? $design_raw : array();

	if ( '' === $design_initialized_raw ) {
		$has_non_empty_design = false;
		foreach ( $design_raw as $design_value ) {
			if ( is_string( $design_value ) && '' !== trim( $design_value ) ) {
				$has_non_empty_design = true;
				break;
			}
			if ( is_numeric( $design_value ) ) {
				$has_non_empty_design = true;
				break;
			}
			if ( is_bool( $design_value ) && true === $design_value ) {
				$has_non_empty_design = true;
				break;
			}
		}
		$design_initialized = $has_non_empty_design;
	} else {
		$design_initialized = (bool) absint( $design_initialized_raw );
	}

	$design_unlock_until_raw = get_post_meta( $playlist_id, '_thespl_design_unlock_until', true );
	$design_unlock_until     = is_numeric( $design_unlock_until_raw ) ? max( 0, (int) $design_unlock_until_raw ) : 0;
	$design_now              = time();
	$design_locked           = false;

	if ( $design_initialized_meta_set && $design_initialized ) {
		if ( 0 === $design_unlock_until ) {
			$design_locked = true;
		} elseif ( $design_unlock_until > 0 && $design_now > $design_unlock_until ) {
			$design_locked = true;
		}
	}

	return array(
		'template_slug' => $template_slug,
		'template_meta' => $template_meta,
		'design'        => $design,
		'flags'         => array(
			'allows_user_css_overrides' => $allows_user_css_overrides,
			'has_audio_info_panel'      => $has_audio_info_panel,
			'show_playlist'             => $show_pl,
			'show_audio_info'           => $show_info,
		),
		'lock'          => array(
			'initialized'          => $design_initialized,
			'initialized_meta_set' => $design_initialized_meta_set,
			'unlock_until'         => $design_unlock_until,
			'now'                  => $design_now,
			'locked'               => $design_locked,
		),
	);
}

/**
 * Convert design schema to CSS variable string for inline styles.
 *
 * @param array $schema Design schema.
 * @return string CSS variable declarations or empty string.
 */
function thespl_design_schema_to_css_vars( $schema ) {
	$schema = is_array( $schema ) ? $schema : array();
	$vars   = array();

	if ( isset( $schema['accent_color'] ) && is_string( $schema['accent_color'] ) ) {
		$vars[] = '--thespl-accent:' . sanitize_hex_color( $schema['accent_color'] );
	}
	if ( isset( $schema['accent_2_color'] ) && is_string( $schema['accent_2_color'] ) ) {
		$vars[] = '--thespl-accent-2:' . sanitize_hex_color( $schema['accent_2_color'] );
	}
	if ( isset( $schema['base_color'] ) && is_string( $schema['base_color'] ) ) {
		$vars[] = '--thespl-bg:' . sanitize_hex_color( $schema['base_color'] );
	}
	if ( isset( $schema['text_color'] ) && is_string( $schema['text_color'] ) ) {
		$vars[] = '--thespl-text:' . sanitize_hex_color( $schema['text_color'] );
	}
	if ( isset( $schema['waveform_color'] ) && is_string( $schema['waveform_color'] ) ) {
		$vars[] = '--thespl-waveform:' . sanitize_hex_color( $schema['waveform_color'] );
	}
	if ( isset( $schema['ring_base_color'] ) && is_string( $schema['ring_base_color'] ) ) {
		$vars[] = '--thespl-ring-base:' . sanitize_hex_color( $schema['ring_base_color'] );
	}
	if ( isset( $schema['button_bg_color'] ) && is_string( $schema['button_bg_color'] ) ) {
		$vars[] = '--thespl-button-bg:' . sanitize_hex_color( $schema['button_bg_color'] );
	}
	if ( isset( $schema['button_text_color'] ) && is_string( $schema['button_text_color'] ) ) {
		$vars[] = '--thespl-button-text:' . sanitize_hex_color( $schema['button_text_color'] );
	}
	if ( isset( $schema['button_active_bg_color'] ) && is_string( $schema['button_active_bg_color'] ) ) {
		$vars[] = '--thespl-button-active-bg:' . sanitize_hex_color( $schema['button_active_bg_color'] );
	}
	if ( isset( $schema['button_active_text_color'] ) && is_string( $schema['button_active_text_color'] ) ) {
		$vars[] = '--thespl-button-active-text:' . sanitize_hex_color( $schema['button_active_text_color'] );
	}
	if ( isset( $schema['chip_bg_color'] ) && is_string( $schema['chip_bg_color'] ) ) {
		$vars[] = '--thespl-chip-bg:' . sanitize_hex_color( $schema['chip_bg_color'] );
	}
	if ( isset( $schema['chip_br_color'] ) && is_string( $schema['chip_br_color'] ) ) {
		$vars[] = '--thespl-chip-br:' . sanitize_hex_color( $schema['chip_br_color'] );
	}

	$text = '';
	if ( isset( $schema['text_color'] ) && is_string( $schema['text_color'] ) ) {
		$text = sanitize_hex_color( $schema['text_color'] );
	}
	if ( '' !== $text ) {
		$hex = ltrim( $text, '#' );
		$hex = preg_replace( '/[^0-9a-fA-F]/', '', $hex );
		if ( 3 === strlen( $hex ) ) {
			$hex = str_repeat( substr( $hex, 0, 1 ), 2 ) . str_repeat( substr( $hex, 1, 1 ), 2 ) . str_repeat( substr( $hex, 2, 1 ), 2 );
		}
		if ( 6 === strlen( $hex ) ) {
			$r        = hexdec( substr( $hex, 0, 2 ) );
			$g        = hexdec( substr( $hex, 2, 2 ) );
			$b        = hexdec( substr( $hex, 4, 2 ) );
			$muted    = 'rgba(' . $r . ',' . $g . ',' . $b . ',0.7)';
			$panel_bg = 'rgba(' . $r . ',' . $g . ',' . $b . ',0.05)';
			$panel_br = 'rgba(' . $r . ',' . $g . ',' . $b . ',0.12)';
			$vars[]   = '--thespl-muted:' . $muted;
			$vars[]   = '--thespl-panel-bg:' . $panel_bg;
			$vars[]   = '--thespl-panel-br:' . $panel_br;
		}
	}

	if ( empty( $vars ) ) {
		return '';
	}

	return implode( '; ', $vars );
}
