<?php
/**
 * Frontend Controller Class
 */

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

class Plugtuner_Public {

	/**
	 * Tracks whether the player has already been rendered on the current page load.
	 *
	 * @var bool
	 */
	private $player_rendered = false;

	/**
	 * Constructor
	 */
	public function __construct() {
		// Enqueue scripts and styles
		add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) );

		// Render persistent player on multiple hooks to guarantee compatibility with all themes
		add_action( 'wp_body_open', array( $this, 'inject_footer_player' ) );
		add_action( 'wp_footer', array( $this, 'inject_footer_player' ) );
		add_action( 'get_footer', array( $this, 'inject_footer_player' ) );

		// Register Shortcode
		add_shortcode( 'plugtuner_radio_player', array( $this, 'render_shortcode_player' ) );

		// AJAX handlers for incrementing stats
		add_action( 'wp_ajax_plugtuner_increment_plays', array( $this, 'ajax_increment_plays' ) );
		add_action( 'wp_ajax_nopriv_plugtuner_increment_plays', array( $this, 'ajax_increment_plays' ) );

		add_action( 'wp_ajax_plugtuner_toggle_like', array( $this, 'ajax_toggle_like' ) );
		add_action( 'wp_ajax_nopriv_plugtuner_toggle_like', array( $this, 'ajax_toggle_like' ) );
	}

	/**
	 * Enqueue Public Frontend Assets
	 */
	public function enqueue_frontend_assets() {
		$settings = get_option( 'plugtuner_settings', array() );
		$enable_footer = isset( $settings['enable_footer_player'] ) ? $settings['enable_footer_player'] : '1';

		// Register FontAwesome locally (GDPR compliant)
		wp_register_style(
			'plugtuner-font-awesome',
			PLUGTUNER_URL . 'public/css/vendor/all.min.css',
			array(),
			file_exists( PLUGTUNER_PATH . 'public/css/vendor/all.min.css' ) ? '6.4.0.' . filemtime( PLUGTUNER_PATH . 'public/css/vendor/all.min.css' ) : '6.4.0'
		);

		// Register Local Google Fonts (GDPR compliant)
		wp_register_style(
			'plugtuner-local-fonts',
			PLUGTUNER_URL . 'public/css/plugtuner-fonts.css',
			array(),
			PLUGTUNER_VERSION
		);

		// Register stylesheet scoped to our tuner
		wp_register_style(
			'plugtuner-public-style',
			PLUGTUNER_URL . 'public/css/plugtuner-player.css',
			array( 'plugtuner-local-fonts' ),
			PLUGTUNER_VERSION . '.' . filemtime( PLUGTUNER_PATH . 'public/css/plugtuner-player.css' )
		);

		// Attach the dynamic design CSS (accent colors, typography) to the player
		// stylesheet instead of printing a raw <style> tag in the head.
		wp_add_inline_style( 'plugtuner-public-style', $this->get_dynamic_css() );

		// Register scripts (radio.js depends on jquery, others depend on radio.js)
		wp_register_script(
			'plugtuner-radio-js',
			PLUGTUNER_URL . 'public/js/radio.js',
			array( 'jquery' ),
			PLUGTUNER_VERSION,
			true
		);

		wp_register_script(
			'plugtuner-station-cards-js',
			PLUGTUNER_URL . 'public/js/station-cards.js',
			array( 'jquery', 'plugtuner-radio-js' ),
			PLUGTUNER_VERSION,
			true
		);

		wp_register_script(
			'plugtuner-main-js',
			PLUGTUNER_URL . 'public/js/main.js',
			array( 'jquery', 'plugtuner-radio-js' ),
			PLUGTUNER_VERSION,
			true
		);

		// Prepare stations list
		$stations_fm = get_option( 'plugtuner_stations', array() );
		if ( ! is_array( $stations_fm ) ) {
			$stations_fm = array();
		}
		$stations_am = get_option( 'plugtuner_stations_am', array() );
		if ( ! is_array( $stations_am ) ) {
			$stations_am = array();
		}
		$stations = array_merge( $stations_fm, $stations_am );

		// Normalize station cover images to absolute URLs
		foreach ( $stations as &$station ) {
			$img_src = '';
			if ( ! empty( $station['image_id'] ) ) {
				$img_src = wp_get_attachment_image_url( $station['image_id'], 'full' );
			}
			if ( empty( $img_src ) && ! empty( $station['image'] ) ) {
				$raw_image = $station['image'];
				if ( strpos( $raw_image, 'http' ) === 0 || strpos( $raw_image, '//' ) === 0 ) {
					$img_src = $raw_image;
				} elseif ( strpos( $raw_image, 'wp-content/' ) !== false ) {
					$img_src = site_url( '/' . ltrim( $raw_image, '/' ) );
				} else {
					$img_src = PLUGTUNER_URL . 'public/' . ltrim( $raw_image, '/' );
				}
			}
			if ( empty( $img_src ) ) {
				$station['image'] = PLUGTUNER_URL . 'public/images/tuner-image.jpg';
				$tuner_path = PLUGTUNER_PATH . 'public/images/tuner-image.jpg';
				if ( file_exists( $tuner_path ) ) {
					$station['image'] = add_query_arg( 't', filemtime( $tuner_path ), $station['image'] );
				}
			} else {
				$station['image'] = $img_src;
				// Add cache buster to force browser to load fresh image if edited
				$updated_time = isset( $station['updated'] ) ? $station['updated'] : time();
				$station['image'] = add_query_arg( 't', $updated_time, $station['image'] );
			}
		}

		$default_image = PLUGTUNER_URL . 'public/images/tuner-image.jpg';
		$tuner_path = PLUGTUNER_PATH . 'public/images/tuner-image.jpg';
		if ( file_exists( $tuner_path ) ) {
			$default_image = add_query_arg( 't', filemtime( $tuner_path ), $default_image );
		}

		// Localize parameters for Javascript
		wp_localize_script(
			'plugtuner-radio-js',
			'plugtuner_public_vars',
			array(
				'ajax_url'        => admin_url( 'admin-ajax.php' ),
				'nonce'           => wp_create_nonce( 'plugtuner_public_nonce' ),
				'plugin_url'      => PLUGTUNER_URL,
				'default_image'   => $default_image,
				'stations'        => $stations,
				'enable_pjax'     => isset( $settings['enable_pjax'] ) ? $settings['enable_pjax'] : '1',
				'enable_autoplay' => isset( $settings['enable_autoplay'] ) ? $settings['enable_autoplay'] : '1',
			)
		);

		// Only load the assets globally when the persistent footer player is enabled.
		// When it is disabled, the shortcode enqueues them on demand.
		if ( '1' === $enable_footer ) {
			$this->enqueue_player_assets();
		}
	}

	/**
	 * Enqueue the registered player styles and scripts.
	 */
	private function enqueue_player_assets() {
		wp_enqueue_style( 'plugtuner-font-awesome' );
		wp_enqueue_style( 'plugtuner-local-fonts' );
		wp_enqueue_style( 'plugtuner-public-style' );
		wp_enqueue_script( 'plugtuner-radio-js' );
		wp_enqueue_script( 'plugtuner-station-cards-js' );
		wp_enqueue_script( 'plugtuner-main-js' );
	}

	/**
	 * Make a stored value safe to place inside a CSS declaration.
	 *
	 * Escaping is context-specific and core has no helper for stylesheet output.
	 * sanitize_text_field() keeps quotes, semicolons and braces, any one of which
	 * lets a saved setting close the declaration and append rules of its own, so
	 * a font name is reduced to the characters a font name can actually need.
	 *
	 * @param string $value Raw option value.
	 * @return string
	 */
	private function css_safe_font_family( $value ) {
		return trim( preg_replace( '/[^A-Za-z0-9 _-]/', '', (string) $value ) );
	}

	/**
	 * Make a stored URL safe to place inside a CSS url() token.
	 *
	 * esc_url_raw() is meant for storage, not for stylesheets: it leaves quotes
	 * and parentheses intact, which is enough to break out of url() and out of
	 * the rule. Anything carrying meaning inside a stylesheet is dropped rather
	 * than mangled, so a hostile value yields no @font-face at all.
	 *
	 * @param string $value Raw option value.
	 * @return string Empty string when the URL cannot be used safely.
	 */
	private function css_safe_url( $value ) {
		$value = esc_url_raw( (string) $value, array( 'http', 'https' ) );
		if ( '' === $value || preg_match( '/["\'()\\\\\s]/', $value ) ) {
			return '';
		}
		return $value;
	}

	/**
	 * Build the dynamic design CSS (accent colors, backgrounds, typography).
	 *
	 * Returned as a string so it can be attached to the player stylesheet with
	 * wp_add_inline_style() instead of being printed as a raw <style> tag.
	 *
	 * @return string CSS.
	 */
	private function get_dynamic_css() {
		$settings = get_option( 'plugtuner_settings', array() );
		if ( ! is_array( $settings ) ) {
			$settings = array();
		}

		// Global fallback accent.
		$accent = isset( $settings['accent_color'] ) ? sanitize_hex_color( $settings['accent_color'] ) : '#ff6f00';
		if ( ! $accent ) {
			$accent = '#ff6f00';
		}

		$css  = ':root{';
		$css .= '--rtp-accent-color:' . $accent . ';';
		$css .= '--rtp-accent-rgb:' . $this->hex_to_rgb_string( $accent ) . ';';
		$css .= '}';

		foreach ( array( 'free-light', 'free-dark' ) as $theme ) {
			$prefix     = str_replace( '-', '_', $theme ) . '_';
			$is_dark    = ( strpos( $theme, 'dark' ) !== false );
			$default_bg = $is_dark ? '#0b0b0c' : '#ffffff';

			$theme_accent = isset( $settings[ $prefix . 'accent_color' ] ) ? sanitize_hex_color( $settings[ $prefix . 'accent_color' ] ) : '#ff6f00';
			if ( ! $theme_accent ) {
				$theme_accent = '#ff6f00';
			}
			$theme_bg = isset( $settings[ $prefix . 'bg_color' ] ) ? sanitize_hex_color( $settings[ $prefix . 'bg_color' ] ) : $default_bg;
			if ( ! $theme_bg ) {
				$theme_bg = $default_bg;
			}

			$theme_opacity     = isset( $settings[ $prefix . 'opacity' ] ) ? intval( $settings[ $prefix . 'opacity' ] ) : 100;
			$theme_blur        = isset( $settings[ $prefix . 'blur' ] ) ? intval( $settings[ $prefix . 'blur' ] ) : 20;
			$theme_font_family = isset( $settings[ $prefix . 'digit_font_family' ] ) ? $this->css_safe_font_family( $settings[ $prefix . 'digit_font_family' ] ) : 'default';
			$theme_font_size   = isset( $settings[ $prefix . 'digit_font_size' ] ) ? intval( $settings[ $prefix . 'digit_font_size' ] ) : 65;
			$theme_font_url    = isset( $settings[ $prefix . 'digit_custom_font_url' ] ) ? $this->css_safe_url( $settings[ $prefix . 'digit_custom_font_url' ] ) : '';

			$theme_accent_rgb  = $this->hex_to_rgb_string( $theme_accent );
			$theme_bg_rgb      = $this->hex_to_rgb_string( $theme_bg );
			$theme_opacity_val = number_format( $theme_opacity / 100, 2, '.', '' );
			$cover_rgb         = $is_dark ? '255, 255, 255' : '0, 0, 0';
			$cover_alpha       = $is_dark ? number_format( $theme_opacity_val * 0.15, 2, '.', '' ) : '0.02';
			$font_face_name    = 'plugtuner_custom_font_' . str_replace( '-', '_', $theme );
			$has_custom_font   = ( 'custom' === $theme_font_family && ! empty( $theme_font_url ) );

			if ( $has_custom_font ) {
				$css .= '@font-face{';
				$css .= "font-family:'" . $font_face_name . "';";
				$css .= "src:url('" . $theme_font_url . "') format('truetype');";
				$css .= 'font-weight:800;font-style:normal;';
				$css .= '}';
			}

			$css .= '.floating-player-card.rtp-design-' . $theme . '{';
			$css .= '--bg-color:' . $theme_bg . ';';
			$css .= '--card-bg:rgba(' . $theme_bg_rgb . ',' . $theme_opacity_val . ');';
			$css .= '--cover-bg:rgba(' . $cover_rgb . ',' . $cover_alpha . ');';
			$css .= '--rtp-accent-color:' . $theme_accent . ';';
			$css .= '--rtp-accent-rgb:' . $theme_accent_rgb . ';';
			$css .= '--primary-orange:' . $theme_accent . ';';
			$css .= '--primary-orange-hover:' . $theme_accent . ';';
			$css .= 'backdrop-filter:blur(' . $theme_blur . 'px);';
			$css .= '-webkit-backdrop-filter:blur(' . $theme_blur . 'px);';
			$css .= '}';

			$css .= '.floating-player-card.rtp-design-' . $theme . ' .active-station-freq{';
			if ( $has_custom_font ) {
				$css .= "font-family:'" . $font_face_name . "',sans-serif !important;";
			} elseif ( 'default' !== $theme_font_family ) {
				$css .= "font-family:'" . $theme_font_family . "',sans-serif !important;";
			}
			$css .= 'font-size:' . $theme_font_size . 'px !important;';
			$css .= '}';
		}

		return $css;
	}

	/**
	 * Inject Floating Player into footer
	 */
	public function inject_footer_player() {
		if ( $this->player_rendered ) {
			return;
		}

		$settings = get_option( 'plugtuner_settings', array() );
		$enable_footer = isset( $settings['enable_footer_player'] ) ? $settings['enable_footer_player'] : '1';

		if ( '1' !== $enable_footer ) {
			return;
		}

		$this->player_rendered = true;

		// Render Player Markup
		$this->render_player_markup( true );
	}

	/**
	 * Shortcode Renderer
	 */
	public function render_shortcode_player( $atts ) {
		// Make sure assets are loaded when the player is embedded via shortcode
		// (they are skipped globally when the footer player is disabled).
		$this->enqueue_player_assets();

		ob_start();
		$this->render_player_markup( false );
		return ob_get_clean();
	}

	/**
	 * Render Player Markup
	 */
	private function render_player_markup( $is_floating = true ) {
		$settings   = get_option( 'plugtuner_settings', array() );
		$width_mode = isset( $settings['player_width_mode'] ) ? $settings['player_width_mode'] : 'fullwidth';
		$theme      = isset( $settings['tuner_theme'] ) ? $settings['tuner_theme'] : 'free-dark';
		if ( ! in_array( $theme, array( 'free-light', 'free-dark' ), true ) ) {
			$theme = 'free-dark';
		}

		$class  = $is_floating ? 'rtp-floating-player' : 'rtp-inline-player';
		$class .= ' rtp-layout-' . $width_mode;
		$class .= ' rtp-design-' . $theme;
		?>
		<div class="floating-player-card <?php echo esc_attr( $class ); ?>" id="rtp-player-card">
			
			<?php if ( $is_floating ) : ?>
				<!-- Minimize Button (for floating view) -->
				<button class="rtp-minimize-btn" aria-label="<?php esc_attr_e( 'Minimize Player', 'plugtuner-radio-player' ); ?>">
					<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width="20" height="20" fill="currentColor">
						<path d="M160 144C151.2 144 144 151.2 144 160L144 480C144 488.8 151.2 496 160 496L480 496C488.8 496 496 488.8 496 480L496 160C496 151.2 488.8 144 480 144L160 144zM96 160C96 124.7 124.7 96 160 96L480 96C515.3 96 544 124.7 544 160L544 480C544 515.3 515.3 544 480 544L160 544C124.7 544 96 515.3 96 480L96 160zM303 417L231 345C221.6 335.6 221.6 320.4 231 311.1C240.4 301.8 255.6 301.7 264.9 311.1L295.9 342.1L295.9 240C295.9 226.7 306.6 216 319.9 216C333.2 216 343.9 226.7 343.9 240L343.9 342.1L374.9 311.1C384.3 301.7 399.5 301.7 408.8 311.1C418.1 320.5 418.2 335.7 408.8 345L336.8 417C327.4 426.4 312.2 426.4 302.9 417z"/>
					</svg>
				</button>

				<!-- Minimized View Bar -->
				<div class="rtp-minimized-bar">
					<div class="rtp-minimized-info">
						<div class="rtp-minimized-cover">
							<?php 
							$default_cover = PLUGTUNER_URL . 'public/images/tuner-image.jpg';
							$tuner_path = PLUGTUNER_PATH . 'public/images/tuner-image.jpg';
							if ( file_exists( $tuner_path ) ) {
								$default_cover = add_query_arg( 't', filemtime( $tuner_path ), $default_cover );
							}
							?>
							<img src="<?php echo esc_url( $default_cover ); ?>" alt="" class="rtp-minimized-cover-img">
						</div>
						<div class="rtp-minimized-meta">
							<span class="rtp-minimized-title"><?php esc_html_e( 'Loading...', 'plugtuner-radio-player' ); ?></span>
							<span class="rtp-minimized-desc"><?php esc_html_e( 'FM Dial Scanner', 'plugtuner-radio-player' ); ?></span>
						</div>
					</div>
					<div class="rtp-minimized-actions">
						<button class="rtp-minimized-play-btn" aria-label="<?php esc_attr_e( 'Play/Pause', 'plugtuner-radio-player' ); ?>">
							<i class="fa-solid fa-play"></i>
						</button>
						<button class="rtp-minimized-expand-btn" aria-label="<?php esc_attr_e( 'Expand Player', 'plugtuner-radio-player' ); ?>">
							<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" width="16" height="16" fill="currentColor">
								<path d="M240 96C248.8 96 256 103.2 256 112C256 120.8 248.8 128 240 128L128 128L128 240C128 248.8 120.8 256 112 256C103.2 256 96 248.8 96 240L96 112C96 103.2 103.2 96 112 96L240 96zM96 400C96 391.2 103.2 384 112 384C120.8 384 128 391.2 128 400L128 512L240 512C248.8 512 256 519.2 256 528C256 536.8 248.8 544 240 544L112 544C103.2 544 96 536.8 96 528L96 400zM528 96C536.8 96 544 103.2 544 112L544 240C544 248.8 536.8 256 528 256C519.2 256 512 248.8 512 240L512 128L400 128C391.2 128 384 120.8 384 112C384 103.2 391.2 96 400 96L528 96zM512 400C512 391.2 519.2 384 528 384C536.8 384 544 391.2 544 400L544 528C544 536.8 536.8 544 528 544L400 544C391.2 544 384 536.8 384 528C384 519.2 391.2 512 400 512L512 512L512 400z"/>
							</svg>
						</button>
					</div>
				</div>
			<?php endif; ?>
			
			<!-- Player Left: Station info & playback control -->
			<div class="player-station-info">
				<div class="player-cover">
					<?php 
					$default_cover = PLUGTUNER_URL . 'public/images/tuner-image.jpg';
					$tuner_path = PLUGTUNER_PATH . 'public/images/tuner-image.jpg';
					if ( file_exists( $tuner_path ) ) {
						$default_cover = add_query_arg( 't', filemtime( $tuner_path ), $default_cover );
					}
					?>
					<img src="<?php echo esc_url( $default_cover ); ?>" alt="<?php esc_attr_e( 'Station Cover', 'plugtuner-radio-player' ); ?>" class="player-cover-img">
				</div>
				<div class="player-meta">
					<div class="live-status">
						<span class="live-dot"></span> <?php esc_html_e( 'LIVE ON AIR', 'plugtuner-radio-player' ); ?>
					</div>
					<h3 class="track-title-name"><?php esc_html_e( 'Loading Stations...', 'plugtuner-radio-player' ); ?></h3>
					<p class="track-artist-desc"><?php esc_html_e( 'FM Dial Scanner', 'plugtuner-radio-player' ); ?></p>
					<div class="player-action-icons">
						<button class="icon-btn rtp-like-btn" id="rtp-like-btn" aria-label="<?php esc_attr_e( 'Like Station', 'plugtuner-radio-player' ); ?>">
							<i class="fa-regular fa-thumbs-up"></i>
							<span class="rtp-like-count">0</span>
						</button>
						<button class="icon-btn rtp-dislike-btn" id="rtp-dislike-btn" aria-label="<?php esc_attr_e( 'Dislike Station', 'plugtuner-radio-player' ); ?>">
							<i class="fa-regular fa-thumbs-down"></i>
							<span class="rtp-dislike-count">0</span>
						</button>
						<button class="icon-btn rtp-share-btn" id="rtp-share-btn" aria-label="<?php esc_attr_e( 'Share', 'plugtuner-radio-player' ); ?>"><i class="fa-solid fa-share-nodes"></i></button>
						<button class="icon-btn rtp-info-btn" id="rtp-info-btn" aria-label="<?php esc_attr_e( 'More Actions', 'plugtuner-radio-player' ); ?>"><i class="fa-solid fa-ellipsis"></i></button>
					</div>
				</div>
			</div>

			<!-- Player Center: Ruler / Tuning Scale -->
			<div class="player-tuner-section">
				<div class="tuner-header">
					<button class="tuner-arrow btn-scale-left" id="btn-scale-left" aria-label="<?php esc_attr_e( 'Tune Down', 'plugtuner-radio-player' ); ?>">
						<i class="fa-solid fa-chevron-left"></i>
					</button>
						<div class="tuner-title">
							<span class="tuner-prefix"><?php esc_html_e( 'FM', 'plugtuner-radio-player' ); ?></span>
							<span class="active-station-freq">88.0</span>
							<span class="tuner-suffix"><?php esc_html_e( 'MHz', 'plugtuner-radio-player' ); ?></span>
						</div>
					<button class="tuner-arrow btn-scale-right" id="btn-scale-right" aria-label="<?php esc_attr_e( 'Tune Up', 'plugtuner-radio-player' ); ?>">
						<i class="fa-solid fa-chevron-right"></i>
					</button>
				</div>

				<div class="tuner-scale-wrapper">
					<div class="tuner-scale-container" id="scale-container">
						<!-- Scale Lines Background -->
						<div class="tuner-lines"></div>
						
						<!-- Scale Labels -->
						<div class="tuner-labels">
							<span>88</span>
							<span>90</span>
							<span>92</span>
							<span>94</span>
							<span>96</span>
							<span>98</span>
							<span>100</span>
							<span>102</span>
							<span>104</span>
							<span>106</span>
							<span>108</span>
						</div>

						<!-- Needle Pointer -->
						<div class="tuner-needle" id="radio-needle">
							<span class="needle-line"></span>
							<span class="needle-knob"></span>
						</div>
					</div>
				</div>
			</div>

			<!-- Player Right: Master Volume & Audio Controls -->
			<div class="player-controls-section rtp-free-light-layout">
				<!-- Free Light Audio Visualizer Markup -->
				<div class="rtp-visualizer-header">
					<div class="eq-status-indicator active" style="margin: 0;">
						<span class="status-dot"></span>
						<span class="status-text"><?php esc_html_e( 'Audio Visualizer', 'plugtuner-radio-player' ); ?></span>
					</div>
				</div>
				<div class="rtp-visualizer-spectrum-section">
					<div class="rtp-visualizer-bars-wrapper">
						<?php for ( $i = 0; $i < 20; $i++ ) : ?>
							<div class="rtp-visualizer-bar">
								<span class="rtp-bar-inner"></span>
							</div>
						<?php endfor; ?>
					</div>
				</div>
				<div class="player-controls-divider"></div>
				<div class="player-volume-play-row">
					<button class="volume-icon-btn volume-mute-btn" id="volume-mute-btn" aria-label="<?php esc_attr_e( 'Mute/Unmute', 'plugtuner-radio-player' ); ?>">
						<svg class="icon-volume" viewBox="0 0 640 640" fill="currentColor">
							<path d="M176 384L112 384C103.2 384 96 376.8 96 368L96 272C96 263.2 103.2 256 112 256L176 256C184.5 256 192.6 252.6 198.6 246.6L316.7 128.6C317.1 128.2 317.6 128 318.1 128C319.2 128 320 128.9 320 129.9L320 510C320 511.1 319.1 511.9 318.1 511.9C317.6 511.9 317.1 511.7 316.7 511.3L198.6 393.4C192.6 387.4 184.5 384 176 384zM176 224L112 224C85.5 224 64 245.5 64 272L64 368C64 394.5 85.5 416 112 416L176 416L294.1 534.1C300.5 540.5 309.1 544 318.1 544C336.8 544 352 528.8 352 510.1L352 130C352 111.3 336.8 96.1 318.1 96.1C309.1 96.1 300.5 99.7 294.1 106L176 224zM419.2 246.4C413.9 253.5 415.3 263.5 422.4 268.8C438 280.5 448 299.1 448 320C448 340.9 438 359.5 422.4 371.2C415.3 376.5 413.9 386.5 419.2 393.6C424.5 400.7 434.5 402.1 441.6 396.8C464.9 379.3 480 351.4 480 320C480 288.6 464.9 260.7 441.6 243.2C434.5 237.9 424.5 239.3 419.2 246.4zM506.2 171.9C499.4 166.3 489.3 167.2 483.7 174C478.1 180.8 479 190.9 485.8 196.5C521.4 225.9 544 270.3 544 320C544 369.7 521.4 414.1 485.8 443.4C479 449 478 459.1 483.7 465.9C489.4 472.7 499.4 473.7 506.2 468.1C548.8 432.9 576 379.6 576 320C576 260.4 548.8 207.1 506.2 171.9z"/>
						</svg>
					</button>
					<div class="volume-slider-wrapper">
						<input type="range" class="volume-slider" min="0" max="100" value="80" aria-label="<?php esc_attr_e( 'Volume', 'plugtuner-radio-player' ); ?>">
						<div class="volume-slider-fill"></div>
					</div>
					<button class="player-play-btn" id="player-play-btn" aria-label="<?php esc_attr_e( 'Play/Pause', 'plugtuner-radio-player' ); ?>">
						<i class="fa-solid fa-play"></i>
					</button>
				</div>
			</div>

		</div>
		<?php
	}

	/**
	 * Helper: Convert Hex color to RGB string (for opacity styling)
	 */
	private function hex_to_rgb_string( $hex ) {
		$hex = str_replace( '#', '', $hex );
		if ( strlen( $hex ) === 3 ) {
			$r = hexdec( substr( $hex, 0, 1 ) . substr( $hex, 0, 1 ) );
			$g = hexdec( substr( $hex, 1, 1 ) . substr( $hex, 1, 1 ) );
			$b = hexdec( substr( $hex, 2, 1 ) . substr( $hex, 2, 1 ) );
		} else {
			$r = hexdec( substr( $hex, 0, 2 ) );
			$g = hexdec( substr( $hex, 2, 2 ) );
			$b = hexdec( substr( $hex, 4, 2 ) );
		}
		return "$r, $g, $b";
	}

	/**
	 * AJAX: Record a play action (increase count)
	 */
	public function ajax_increment_plays() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'plugtuner_public_nonce' ) ) {
			wp_send_json_error( 'Invalid security token' );
		}

		$url = isset( $_POST['stream_url'] ) ? esc_url_raw( wp_unslash( $_POST['stream_url'] ) ) : '';

		if ( ! empty( $url ) ) {
			// Stations live in two options: FM and AM.
			foreach ( array( 'plugtuner_stations', 'plugtuner_stations_am' ) as $option_key ) {
				$stations = get_option( $option_key, array() );
				if ( ! is_array( $stations ) ) {
					continue;
				}
				foreach ( $stations as &$station ) {
					if ( isset( $station['url'] ) && $station['url'] === $url ) {
						$station['plays'] = isset( $station['plays'] ) ? (int) $station['plays'] + 1 : 1;
						update_option( $option_key, $stations );
						wp_send_json_success( array( 'plays' => $station['plays'] ) );
					}
				}
				unset( $station );
			}
		}
		wp_send_json_error( 'Station not found' );
	}

	/**
	 * AJAX: Toggle a like on a station
	 */
	public function ajax_toggle_like() {
		if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'plugtuner_public_nonce' ) ) {
			wp_send_json_error( 'Invalid security token' );
		}

		$url    = isset( $_POST['stream_url'] ) ? esc_url_raw( wp_unslash( $_POST['stream_url'] ) ) : '';
		$type   = isset( $_POST['type'] ) ? sanitize_key( wp_unslash( $_POST['type'] ) ) : 'like'; // 'like' or 'dislike'
		$status = isset( $_POST['status'] ) ? sanitize_key( wp_unslash( $_POST['status'] ) ) : 'active'; // 'active' (increment) or 'inactive' (decrement)

		if ( ! empty( $url ) ) {
			// Stations live in two options: FM and AM.
			foreach ( array( 'plugtuner_stations', 'plugtuner_stations_am' ) as $option_key ) {
				$stations = get_option( $option_key, array() );
				if ( ! is_array( $stations ) ) {
					continue;
				}
				foreach ( $stations as &$station ) {
					if ( isset( $station['url'] ) && $station['url'] === $url ) {
						$likes    = isset( $station['likes'] ) ? (int) $station['likes'] : 0;
						$dislikes = isset( $station['dislikes'] ) ? (int) $station['dislikes'] : 0;

						if ( 'like' === $type ) {
							if ( 'active' === $status ) {
								$likes = $likes + 1;
							} else {
								$likes = max( 0, $likes - 1 );
							}
						} elseif ( 'dislike' === $type ) {
							if ( 'active' === $status ) {
								$dislikes = $dislikes + 1;
							} else {
								$dislikes = max( 0, $dislikes - 1 );
							}
						}

						$station['likes']    = $likes;
						$station['dislikes'] = $dislikes;

						update_option( $option_key, $stations );
						wp_send_json_success( array( 
							'likes'    => $likes,
							'dislikes' => $dislikes 
						) );
					}
				}
				unset( $station );
			}
		}

		wp_send_json_error( 'Station not found' );
	}

}
