<?php
/**
 * Admin Settings Handlers.
 *
 * @package TheStudioPlayer
 */

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

/**
 * Handle Save Settings.
 */
function thespl_handle_save_settings() {
	check_ajax_referer( 'thespl_muxer_nonce', 'nonce' );
	if ( ! thespl_current_user_can_policy( 'settings_general' ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied', 'the-studio-player' ) ) );
	}

	$settings = array();
	if ( isset( $_POST['chunk_size'] ) ) {
		$chunk_size = intval( $_POST['chunk_size'] );
		// Whitelist allowed chunk sizes (256KB to 5MB).
		$allowed_sizes = array( 262144, 524288, 1048576, 2097152, 5242880 );

		if ( in_array( $chunk_size, $allowed_sizes, true ) ) {
			$settings['chunk_size'] = $chunk_size;
		} else {
			// Fallback to safe default if invalid value received.
			$settings['chunk_size'] = 524288;
		}
	}

	$forced_subdir = thespl_get_forced_upload_subdir();
	if ( '' !== $forced_subdir ) {
		$settings['subdir'] = $forced_subdir;
	} elseif ( isset( $_POST['subdir'] ) ) {
		$raw_subdir   = sanitize_text_field( wp_unslash( $_POST['subdir'] ) );
		$clean_subdir = thespl_sanitize_subdir_path( $raw_subdir );
		if ( '' !== $clean_subdir ) {
			$settings['subdir'] = $clean_subdir;
		}
	}

	update_option( 'thespl_muxer_settings', $settings );

	// If we changed the directory, make sure it is protected.
	if ( isset( $settings['subdir'] ) ) {
		$upload_dir = wp_upload_dir();
		if ( ! empty( $upload_dir['basedir'] ) && is_string( $upload_dir['basedir'] ) ) {
			$audio_dir  = trailingslashit( trailingslashit( $upload_dir['basedir'] ) . 'the-studio-player/audio' );
			$target_dir = $audio_dir . $settings['subdir'];

			if ( thespl_init_filesystem() ) {
				global $wp_filesystem;
				if ( $wp_filesystem->is_dir( $target_dir ) ) {
					thespl_ensure_directory_protection( $target_dir );
				}
			}
		}
	}

	wp_send_json_success( array( 'message' => __( 'Settings saved successfully', 'the-studio-player' ) ) );
}
add_action( 'wp_ajax_thespl_save_settings', 'thespl_handle_save_settings' );

/**
 * AJAX handler: hide security verification box.
 *
 * @return void
 */
function thespl_ajax_hide_security_verification() {
	check_ajax_referer( 'thespl_muxer_nonce', 'nonce' );

	if ( ! thespl_current_user_can_policy( 'settings_security' ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied.', 'the-studio-player' ) ) );
	}

	$settings                               = thespl_get_player_settings();
	$settings['show_security_verification'] = 0;
	update_option( 'thespl_player_settings', $settings );

	wp_send_json_success( array( 'message' => __( 'Security verification hidden.', 'the-studio-player' ) ) );
}
add_action( 'wp_ajax_thespl_hide_security_verification', 'thespl_ajax_hide_security_verification' );

/**
 * AJAX handler to dismiss the onboarding overlay for the current site.
 *
 * @return void
 */
function thespl_ajax_dismiss_onboarding() {
	check_ajax_referer( 'thespl_dismiss_onboarding', 'nonce' );

	if ( ! thespl_current_user_can_policy( 'plugin_access' ) ) {
		wp_send_json_error( array( 'message' => __( 'Permission denied.', 'the-studio-player' ) ) );
	}

	$settings                       = thespl_get_player_settings();
	$settings['onboarding_enabled'] = 0;
	update_option( 'thespl_player_settings', $settings );

	wp_send_json_success( array( 'message' => __( 'Onboarding dismissed.', 'the-studio-player' ) ) );
}
add_action( 'wp_ajax_thespl_dismiss_onboarding', 'thespl_ajax_dismiss_onboarding' );

/**
 * Register plugin settings and settings fields.
 *
 * @return void
 */
function thespl_register_player_settings() {
	register_setting(
		'thespl_player_settings',
		'thespl_player_settings',
		array(
			'type'              => 'array',
			'sanitize_callback' => 'thespl_sanitize_player_settings',
			'default'           => array(),
		)
	);

	register_setting(
		'thespl_player_settings',
		'thespl_muxer_settings',
		array(
			'type'              => 'array',
			'sanitize_callback' => 'thespl_sanitize_muxer_settings',
			'default'           => array(),
		)
	);

	// UI section.
	add_settings_section(
		'thespl_player_settings_ui',
		__( 'General', 'the-studio-player' ),
		'__return_null',
		'thespl-player-settings'
	);

	add_settings_field(
		'thespl_player_debug_console_enabled',
		__( 'Player Debug Console', 'the-studio-player' ),
		'thespl_render_player_debug_console_field',
		'thespl-player-settings',
		'thespl_player_settings_ui'
	);

	add_settings_field(
		'thespl_player_onboarding_enabled',
		__( 'Onboarding Overlay', 'the-studio-player' ),
		'thespl_render_player_onboarding_enabled_field',
		'thespl-player-settings',
		'thespl_player_settings_ui'
	);

	add_settings_field(
		'thespl_player_remote_content_opt_in',
		__( 'Remote onboarding & documentation', 'the-studio-player' ),
		'thespl_render_remote_content_opt_in_field',
		'thespl-player-settings',
		'thespl_player_settings_ui'
	);

	add_settings_field(
		'thespl_uninstall_remove_uploads',
		__( 'Uninstall behavior', 'the-studio-player' ),
		'thespl_render_uninstall_remove_uploads_field',
		'thespl-player-settings',
		'thespl_player_settings_ui'
	);

	// Audio section.
	add_settings_section(
		'thespl_player_settings_audio',
		__( 'Audio Config', 'the-studio-player' ),
		'__return_null',
		'thespl-player-settings'
	);

	add_settings_field(
		'thespl_player_streaming_auto_detect_network',
		__( 'Auto Detect Network', 'the-studio-player' ),
		'thespl_render_streaming_auto_detect_network_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_field(
		'thespl_player_streaming_chunk_level',
		__( 'Streaming Chunk Size', 'the-studio-player' ),
		'thespl_render_streaming_chunk_level_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_field(
		'thespl_player_streaming_prebuffer_sec',
		__( 'Prebuffer Target (seconds)', 'the-studio-player' ),
		'thespl_render_streaming_prebuffer_sec_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);
	add_settings_field(
		'thespl_player_streaming_continue_buffer_on_pause',
		__( 'Continue Buffering on Pause', 'the-studio-player' ),
		'thespl_render_streaming_continue_buffer_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_field(
		'thespl_player_streaming_prefetch_next_on_ahead',
		__( 'Prefetch next tracks on sufficient buffer', 'the-studio-player' ),
		'thespl_render_streaming_prefetch_next_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_field(
		'thespl_player_streaming_ready_ahead_sec',
		__( 'Ready State Ahead Threshold (seconds)', 'the-studio-player' ),
		'thespl_render_streaming_ready_ahead_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_field(
		'thespl_player_fade_switch_duration_ms',
		__( 'Variant Switch Fade', 'the-studio-player' ),
		'thespl_render_player_fade_switch_duration_field',
		'thespl-player-settings',
		'thespl_player_settings_audio'
	);

	add_settings_section(
		'thespl_player_settings_muxer',
		__( 'Muxer-Uploader', 'the-studio-player' ),
		'__return_null',
		'thespl-player-settings'
	);

	add_settings_field(
		'thespl_muxer_upload_subdir',
		__( 'Upload Subdirectory', 'the-studio-player' ),
		'thespl_render_muxer_upload_subdir_field',
		'thespl-player-settings',
		'thespl_player_settings_muxer'
	);

	// Security section.
	add_settings_section(
		'thespl_player_settings_security',
		__( 'Security & Performance', 'the-studio-player' ),
		'__return_null',
		'thespl-player-settings'
	);

	add_settings_field(
		'thespl_player_streaming_htaccess_enabled',
		__( 'Directory Protection (.htaccess)', 'the-studio-player' ),
		'thespl_render_streaming_htaccess_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_streaming_security_enabled',
		__( 'Token-based Streaming Security', 'the-studio-player' ),
		'thespl_render_streaming_security_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_streaming_token_lifetime',
		__( 'Token Lifetime (minutes)', 'the-studio-player' ),
		'thespl_render_streaming_token_lifetime_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_streaming_rate_limit_enabled',
		__( 'Rate Limiting', 'the-studio-player' ),
		'thespl_render_streaming_rate_limit_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_streaming_rate_limit_rpm',
		__( 'Requests per Minute', 'the-studio-player' ),
		'thespl_render_streaming_rate_limit_rpm_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_streaming_rate_limit_burst',
		__( 'Burst Limit', 'the-studio-player' ),
		'thespl_render_streaming_rate_limit_burst_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_show_security_verification',
		__( 'Show Security Verification', 'the-studio-player' ),
		'thespl_render_player_show_security_verification_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_min_capability',
		__( 'Plugin Access Role', 'the-studio-player' ),
		'thespl_render_player_min_capability_field',
		'thespl-player-settings',
		'thespl_player_settings_security'
	);

	add_settings_field(
		'thespl_player_remote_global_warning_banners_enabled',
		__( 'Global Remote Warning Banners', 'the-studio-player' ),
		function () {
			$settings = thespl_get_player_settings();
			$enabled  = ! empty( $settings['remote_global_warning_banners_enabled'] );
			echo '<label class="thespl-admin-inline-label">';
			echo '<input type="checkbox" name="thespl_player_settings[remote_global_warning_banners_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
			echo '<span>' . esc_html__( 'Allow security-critical remote warning banners on non-Studio-Player admin screens.', 'the-studio-player' ) . '</span>';
			echo '</label>';
		},
		'thespl-player-settings',
		'thespl_player_settings_security'
	);
}
add_action( 'admin_init', 'thespl_register_player_settings' );

/**
 * Filter option page capability for player settings saves.
 *
 * @param string $default_capability Default required capability.
 * @return string Required capability for the settings page.
 */
function thespl_filter_player_settings_page_capability( $default_capability ) {
	$capability = thespl_get_policy_capability( 'plugin_access' );
	if ( '' === $capability ) {
		return $default_capability;
	}
	return $capability;
}
add_filter( 'option_page_capability_thespl_player_settings', 'thespl_filter_player_settings_page_capability' );

/**
 * Sanitize plugin settings.
 *
 * @param array $input Raw settings.
 * @return array Sanitized settings.
 */
function thespl_sanitize_player_settings( $input ) {
	$in                                        = is_array( $input ) ? $input : array();
	$out                                       = array();
	$is_admin_user                             = current_user_can( 'manage_options' );
	$can_manage_general                        = thespl_current_user_can_policy( 'settings_general' );
	$existing_settings                         = get_option( 'thespl_player_settings', array() );
	$current_settings                          = thespl_get_player_settings();
	$out['streaming_auto_detect_network']      = ! empty( $in['streaming_auto_detect_network'] ) ? 1 : 0;
	$out['streaming_continue_buffer_on_pause'] = ! empty( $in['streaming_continue_buffer_on_pause'] ) ? 1 : 0;
	$out['streaming_security_enabled']         = ! empty( $in['streaming_security_enabled'] ) ? 1 : 0;
	$out['streaming_htaccess_enabled']         = ! empty( $in['streaming_htaccess_enabled'] ) ? 1 : 0;
	$out['streaming_rate_limit_enabled']       = ! empty( $in['streaming_rate_limit_enabled'] ) ? 1 : 0;
	$out['show_security_verification']         = ! empty( $in['show_security_verification'] ) ? 1 : 0;

	// Protection: ONLY Administrators can change the min_capability.
	// If a non-admin saves the settings, we keep the existing value.
	$existing_cap = ! empty( $existing_settings['min_capability'] ) ? $existing_settings['min_capability'] : 'manage_options';

	if ( $is_admin_user ) {
		$allowed_caps          = array( 'manage_options', 'edit_others_posts', 'publish_posts' );
		$out['min_capability'] = isset( $in['min_capability'] ) && in_array( $in['min_capability'], $allowed_caps, true ) ? $in['min_capability'] : $existing_cap;
	} else {
		$out['min_capability'] = $existing_cap;
	}

	$token_lifetime = 60;
	if ( isset( $in['streaming_token_lifetime'] ) ) {
		$token_lifetime = is_numeric( $in['streaming_token_lifetime'] ) ? (int) $in['streaming_token_lifetime'] : 60;
	}
	$out['streaming_token_lifetime'] = max( 1, min( 1440, $token_lifetime ) );

	$rpm = 300;
	if ( isset( $in['streaming_rate_limit_rpm'] ) ) {
		$rpm = is_numeric( $in['streaming_rate_limit_rpm'] ) ? (int) $in['streaming_rate_limit_rpm'] : 300;
	}
	$out['streaming_rate_limit_rpm'] = max( 10, min( 1000, $rpm ) );

	$burst = 80;
	if ( isset( $in['streaming_rate_limit_burst'] ) ) {
		$burst = is_numeric( $in['streaming_rate_limit_burst'] ) ? (int) $in['streaming_rate_limit_burst'] : 80;
	}
	$out['streaming_rate_limit_burst'] = max( 5, min( 500, $burst ) );

	$fade_ms = 0;
	if ( isset( $in['fade_switch_duration_ms'] ) ) {
		$fade_ms = is_numeric( $in['fade_switch_duration_ms'] ) ? (int) $in['fade_switch_duration_ms'] : 0;
	}
	if ( $fade_ms < 0 ) {
		$fade_ms = 0;
	}
	if ( $fade_ms > 50 ) {
		$fade_ms = 50;
	}
	$out['fade_switch_duration_ms'] = $fade_ms;

	$chunk_level = 4;
	if ( isset( $in['streaming_chunk_level'] ) ) {
		$chunk_level = is_numeric( $in['streaming_chunk_level'] ) ? (int) $in['streaming_chunk_level'] : 4;
	}
	if ( $chunk_level < 0 ) {
		$chunk_level = 0;
	}
	if ( $chunk_level > 9 ) {
		$chunk_level = 9;
	}
	$out['streaming_chunk_level'] = $chunk_level;

	$prebuffer_sec = 0;
	if ( isset( $in['streaming_prebuffer_sec'] ) ) {
		$prebuffer_sec = is_numeric( $in['streaming_prebuffer_sec'] ) ? (int) $in['streaming_prebuffer_sec'] : 0;
	}
	if ( $prebuffer_sec < 0 ) {
		$prebuffer_sec = 0;
	}
	if ( $prebuffer_sec > 30 ) {
		$prebuffer_sec = 30;
	}
	$out['streaming_prebuffer_sec']          = $prebuffer_sec;
	$out['debug_console_enabled']            = ! empty( $in['debug_console_enabled'] ) ? 1 : 0;
	$out['streaming_prefetch_next_on_ahead'] = ! empty( $in['streaming_prefetch_next_on_ahead'] ) ? 1 : 0;
	$ready_ahead_sec                         = 1;
	if ( isset( $in['streaming_ready_ahead_sec'] ) ) {
		$ready_ahead_sec = is_numeric( $in['streaming_ready_ahead_sec'] ) ? (int) $in['streaming_ready_ahead_sec'] : 1;
	}
	if ( $ready_ahead_sec < 1 ) {
		$ready_ahead_sec = 1;
	}
	if ( $ready_ahead_sec > 10 ) {
		$ready_ahead_sec = 10;
	}
	$out['streaming_ready_ahead_sec'] = $ready_ahead_sec;

	$out['remote_global_warning_banners_enabled'] = ! empty( $in['remote_global_warning_banners_enabled'] ) ? 1 : 0;
	$out['onboarding_enabled']                    = ! empty( $in['onboarding_enabled'] ) ? 1 : 0;

	if ( $can_manage_general && isset( $in['remote_content_opt_in'] ) ) {
		$choice = is_string( $in['remote_content_opt_in'] ) ? strtolower( trim( $in['remote_content_opt_in'] ) ) : '';
		if ( 'yes' === $choice || 'no' === $choice ) {
			update_option( 'thespl_remote_content_opt_in', $choice );
		}
	}

	if ( $can_manage_general && isset( $in['uninstall_remove_uploads'] ) ) {
		$uninstall_choice = is_string( $in['uninstall_remove_uploads'] ) ? strtolower( trim( $in['uninstall_remove_uploads'] ) ) : '';
		if ( 'yes' === $uninstall_choice || 'no' === $uninstall_choice ) {
			update_option( 'thespl_uninstall_remove_uploads', $uninstall_choice );
		}
	}

	// Keep most general settings unchanged for users below Editor role.
	if ( ! $can_manage_general ) {
		$general_restricted_keys = array(
			'debug_console_enabled',
			'streaming_auto_detect_network',
			'streaming_continue_buffer_on_pause',
			'streaming_security_enabled',
			'streaming_htaccess_enabled',
			'streaming_rate_limit_enabled',
			'show_security_verification',
			'min_capability',
			'streaming_token_lifetime',
			'streaming_rate_limit_rpm',
			'streaming_rate_limit_burst',
			'fade_switch_duration_ms',
			'streaming_chunk_level',
			'streaming_prebuffer_sec',
			'streaming_prefetch_next_on_ahead',
			'streaming_ready_ahead_sec',
			'remote_global_warning_banners_enabled',
			'onboarding_enabled',
		);

		foreach ( $general_restricted_keys as $general_key ) {
			if ( isset( $current_settings[ $general_key ] ) ) {
				$out[ $general_key ] = $current_settings[ $general_key ];
			}
		}
	}

	// Keep security-sensitive settings unchanged for non-admin users.
	if ( ! $is_admin_user ) {
		$security_keys = array(
			'streaming_security_enabled',
			'streaming_htaccess_enabled',
			'streaming_rate_limit_enabled',
			'show_security_verification',
			'min_capability',
			'streaming_token_lifetime',
			'streaming_rate_limit_rpm',
			'streaming_rate_limit_burst',
			'remote_global_warning_banners_enabled',
		);

		foreach ( $security_keys as $security_key ) {
			if ( isset( $existing_settings[ $security_key ] ) ) {
				$out[ $security_key ] = $existing_settings[ $security_key ];
			}
		}
	}

	return $out;
}

/**
 * Sanitize muxer settings.
 *
 * @param array $input Raw settings.
 * @return array Sanitized settings.
 */
function thespl_sanitize_muxer_settings( $input ) {
	$in             = is_array( $input ) ? $input : array();
	$muxer_settings = thespl_get_muxer_settings();
	if ( ! thespl_current_user_can_policy( 'settings_general' ) ) {
		return $muxer_settings;
	}

	if ( isset( $in['subdir'] ) ) {
		$muxer_subdir = thespl_sanitize_subdir_path( sanitize_text_field( wp_unslash( $in['subdir'] ) ) );
		if ( '' !== $muxer_subdir ) {
			$muxer_settings['subdir'] = $muxer_subdir;
		} else {
			unset( $muxer_settings['subdir'] );
		}
	}

	if ( isset( $in['chunk_size'] ) ) {
		$muxer_chunk = is_numeric( $in['chunk_size'] ) ? (int) $in['chunk_size'] : 524288;
		$allowed     = array( 262144, 524288, 1048576, 2097152, 5242880 );
		if ( ! in_array( $muxer_chunk, $allowed, true ) ) {
			$muxer_chunk = 524288;
		}
		$muxer_settings['chunk_size'] = $muxer_chunk;
	}

	return $muxer_settings;
}

/**
 * Render settings field: remote content opt-in.
 *
 * @return void
 */
function thespl_render_remote_content_opt_in_field() {
	if ( ! thespl_current_user_can_policy( 'settings_general' ) ) {
		return;
	}
	$state      = thespl_get_remote_opt_in_state();
	$choice_yes = ( '' === $state || 'yes' === $state );
	$choice_no  = ( 'no' === $state );

	echo '<fieldset>';
	echo '<label>';
	echo '<input type="radio" name="thespl_player_settings[remote_content_opt_in]" value="yes" ' . checked( $choice_yes, true, false ) . ' />';
	echo ' ' . esc_html__( 'Load onboarding, documentation, changelog and security notices from studioplayer.de in the Dashboard.', 'the-studio-player' );
	echo '</label><br />';
	echo '<label>';
	echo '<input type="radio" name="thespl_player_settings[remote_content_opt_in]" value="no" ' . checked( $choice_no, true, false ) . ' />';
	echo ' ' . esc_html__( 'Do not load remote content in the Dashboard. Open these pages on studioplayer.de instead.', 'the-studio-player' );
	echo '</label>';
	echo '<p class="description">' . esc_html__( 'Requests include the plugin version, plan (free/pro) and locale. No site content or user data is sent. Standard HTTP metadata (for example your server IP address) is processed when fetching remote content.', 'the-studio-player' ) . '</p>';
	echo '</fieldset>';
}

/**
 * Render settings field: uninstall uploads behavior.
 *
 * @return void
 */
function thespl_render_uninstall_remove_uploads_field() {
	if ( ! thespl_current_user_can_policy( 'settings_general' ) ) {
		return;
	}
	$raw = get_option( 'thespl_uninstall_remove_uploads', '' );
	if ( ! is_string( $raw ) ) {
		$raw = '';
	}
	$state         = strtolower( trim( $raw ) );
	$choice_keep   = ( 'no' === $state || '' === $state );
	$choice_delete = ( 'yes' === $state );
	echo '<fieldset>';
	echo '<label>';
	echo '<input type="radio" name="thespl_player_settings[uninstall_remove_uploads]" value="no" ' . checked( $choice_keep, true, false ) . ' />';
	echo ' ' . esc_html__( 'Keep all files in wp-content/uploads/the-studio-player on uninstall (recommended).', 'the-studio-player' );
	echo '</label><br />';
	echo '<label>';
	echo '<input type="radio" name="thespl_player_settings[uninstall_remove_uploads]" value="yes" ' . checked( $choice_delete, true, false ) . ' />';
	echo ' ' . esc_html__( 'Delete all files in wp-content/uploads/the-studio-player on uninstall.', 'the-studio-player' );
	echo '</label>';
	echo '<p class="description thespl-uninstall-warning" data-thespl-uninstall-warning="settings" style="' . ( $choice_delete ? '' : 'display:none;' ) . 'color:#b32d2e;font-weight:600;">' . esc_html__( 'Warning: the next time you delete this plugin, all Studio Player data and uploads will be permanently removed.', 'the-studio-player' ) . '</p>';
	echo '<p class="description">' . esc_html__( 'This setting controls whether the plugin removes its uploads directory when The Studio Player is uninstalled.', 'the-studio-player' ) . '</p>';
	echo '</fieldset>';
}

/**
 * Render settings field: fade switch duration.
 *
 * @return void
 */
function thespl_render_player_fade_switch_duration_field() {
	$settings = thespl_get_player_settings();
	$val      = isset( $settings['fade_switch_duration_ms'] ) ? (int) $settings['fade_switch_duration_ms'] : 1;
	if ( $val < 0 ) {
		$val = 0;
	}
	if ( $val > 50 ) {
		$val = 50;
	}
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="number" class="small-text" name="thespl_player_settings[fade_switch_duration_ms]" min="0" max="50" step="1" value="' . esc_attr( (string) $val ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Fade duration in ms when switching variants (0 disables).', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render settings field: streaming chunk level.
 *
 * @return void
 */
function thespl_render_streaming_chunk_level_field() {
	$settings = thespl_get_player_settings();
	$auto     = ! empty( $settings['streaming_auto_detect_network'] );
	$val      = isset( $settings['streaming_chunk_level'] ) ? (int) $settings['streaming_chunk_level'] : 4;
	if ( $val < 0 ) {
		$val = 0;
	}
	if ( $val > 9 ) {
		$val = 9;
	}
	$labels = array( '128 KiB', '256 KiB', '512 KiB', '768 KiB', '1 MiB', '1.5 MiB', '2 MiB', '3 MiB', '4 MiB', '6 MiB' );
	$cur    = $labels[ $val ];
	echo '<div id="thespl-chunk-wrapper" class="' . ( $auto ? 'thespl-admin-hidden' : '' ) . '">';
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="range" name="thespl_player_settings[streaming_chunk_level]" min="0" max="9" step="1" value="' . esc_attr( (string) $val ) . '" ' . ( $auto ? 'disabled="disabled"' : '' ) . ' />';
	echo '<span id="thespl-chunk-level-val" class="thespl-admin-value">' . esc_html( $cur ) . '</span>';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Tune streaming latency vs efficiency', 'the-studio-player' ) . '</span>';
	echo '</div></div>';
}

/**
 * Render settings field: streaming prebuffer seconds.
 *
 * @return void
 */
function thespl_render_streaming_prebuffer_sec_field() {
	$settings = thespl_get_player_settings();
	$auto     = ! empty( $settings['streaming_auto_detect_network'] );
	$val      = isset( $settings['streaming_prebuffer_sec'] ) ? (int) $settings['streaming_prebuffer_sec'] : 0;
	if ( $val < 0 ) {
		$val = 0;
	}
	if ( $val > 30 ) {
		$val = 30;
	}
	echo '<div id="thespl-prebuffer-wrapper" class="' . ( $auto ? 'thespl-admin-hidden' : '' ) . '">';
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="range" name="thespl_player_settings[streaming_prebuffer_sec]" min="0" max="30" step="1" value="' . esc_attr( (string) $val ) . '" ' . ( $auto ? 'disabled="disabled"' : '' ) . ' />';
	echo '<span id="thespl-prebuffer-val" class="thespl-admin-value">' . esc_html( $val . ' s' ) . '</span>';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Target buffer ahead in seconds (0 disables)', 'the-studio-player' ) . '</span>';
	echo '</div></div>';
}

/**
 * Render settings field: streaming auto-detect network.
 *
 * @return void
 */
function thespl_render_streaming_auto_detect_network_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_auto_detect_network'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_auto_detect_network]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Automatically detect network and adapt prebuffer/chunk settings.', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render settings field: streaming continue buffering on pause.
 *
 * @return void
 */
function thespl_render_streaming_continue_buffer_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_continue_buffer_on_pause'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_continue_buffer_on_pause]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Continue buffering while paused (best effort, browser-dependent).', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render settings field: streaming prefetch next on ahead.
 *
 * @return void
 */
function thespl_render_streaming_prefetch_next_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_prefetch_next_on_ahead'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_prefetch_next_on_ahead]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Prefetch next track when buffer ahead ≥ 10 s.', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render settings field: streaming ready ahead seconds.
 *
 * @return void
 */
function thespl_render_streaming_ready_ahead_field() {
	$settings = thespl_get_player_settings();
	$val      = isset( $settings['streaming_ready_ahead_sec'] ) ? (int) $settings['streaming_ready_ahead_sec'] : 1;
	if ( $val < 1 ) {
		$val = 1;
	}
	if ( $val > 10 ) {
		$val = 10;
	}
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="number" class="small-text" name="thespl_player_settings[streaming_ready_ahead_sec]" min="1" max="10" step="1" value="' . esc_attr( (string) $val ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Minimum buffered ahead required to show Ready.', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render settings field: debug console toggle.
 *
 * @return void
 */
function thespl_render_player_debug_console_field() {
	if ( ! thespl_current_user_can_policy( 'settings_general' ) ) {
		return;
	}
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['debug_console_enabled'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[debug_console_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Enable debug console overlay in all players (global master switch).', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render settings field: onboarding overlay enabled toggle.
 *
 * @return void
 */
function thespl_render_player_onboarding_enabled_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['onboarding_enabled'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[onboarding_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Show the onboarding overlay (again).', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render muxer upload subdirectory settings field.
 *
 * @return void
 */
function thespl_render_muxer_upload_subdir_field() {
	$muxer          = thespl_get_muxer_settings();
	$default_subdir = $muxer['subdir'];
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="text" id="upload-subdir" name="thespl_muxer_settings[subdir]" value="' . esc_attr( $default_subdir ) . '" placeholder="' . esc_attr__( 'e.g., my-album/track-1', 'the-studio-player' ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Optional directory inside wp-content/uploads/the-studio-player/audio/. Will be created if missing.', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render muxer upload chunk size settings field.
 *
 * @return void
 */
function thespl_render_muxer_chunk_size_field() {
	$muxer         = thespl_get_muxer_settings();
	$val           = isset( $muxer['chunk_size'] ) ? (int) $muxer['chunk_size'] : 524288;
	$allowed_sizes = array(
		262144  => esc_html__( '256 KB (Slow, very safe)', 'the-studio-player' ),
		524288  => esc_html__( '512 KB (Stable)', 'the-studio-player' ),
		1048576 => esc_html__( '1 MB (Standard)', 'the-studio-player' ),
		2097152 => esc_html__( '2 MB (Faster)', 'the-studio-player' ),
		5242880 => esc_html__( '5 MB (Fastest)', 'the-studio-player' ),
	);

	echo '<select name="thespl_muxer_settings[chunk_size]" id="thespl_muxer_chunk_size">';
	foreach ( $allowed_sizes as $size => $label ) {
		echo '<option value="' . esc_attr( (string) $size ) . '" ' . selected( $val, $size, false ) . '>' . esc_html( $label ) . '</option>';
	}
	echo '</select>';
	echo '<p class="description">' . esc_html__( 'Smaller chunks are safer for unstable connections. Larger chunks are faster.', 'the-studio-player' ) . '</p>';
	$upload_limit = size_format( wp_max_upload_size() );
	/* translators: %s: Server upload limit (e.g. 50 MB) */
	echo '<p class="description">' . esc_html( sprintf( __( 'Server Upload Limit: %s', 'the-studio-player' ), $upload_limit ) ) . '</p>';
}

/**
 * Render settings field: streaming security toggle.
 *
 * @return void
 */
function thespl_render_streaming_security_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_security_enabled'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_security_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Protect streaming URLs with temporary tokens (Signed URLs).', 'the-studio-player' ) . '</span>';
	echo '</label>';
	echo '<p class="thespl-admin-warning thespl-security-warn-token" style="color:#d63638; font-weight:bold; margin-top:5px; display:' . ( $enabled ? 'none' : 'block' ) . ';">';
	echo '⚠️ ' . esc_html__( 'Warning: Disabling token security is not recommended. Your streams could be accessed directly by unauthorized users.', 'the-studio-player' );
	echo '</p>';
}

/**
 * Render settings field: htaccess security.
 *
 * @return void
 */
function thespl_render_streaming_htaccess_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_htaccess_enabled'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_htaccess_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Enable automatic .htaccess protection in muxer upload directories (blocks direct file access).', 'the-studio-player' ) . '</span>';
	echo '</label>';
	echo '<p class="thespl-admin-warning thespl-security-warn-htaccess" style="color:#d63638; font-weight:bold; margin-top:5px; display:' . ( $enabled ? 'none' : 'block' ) . ';">';
	echo '⚠️ ' . esc_html__( 'Warning: Disabling directory protection allows direct access to your physical media files if the URL is known.', 'the-studio-player' );
	echo '</p>';
}

/**
 * Render settings field: token lifetime.
 *
 * @return void
 */
function thespl_render_streaming_token_lifetime_field() {
	$settings = thespl_get_player_settings();
	$val      = isset( $settings['streaming_token_lifetime'] ) ? (int) $settings['streaming_token_lifetime'] : 60;
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="number" class="small-text" name="thespl_player_settings[streaming_token_lifetime]" min="1" max="1440" step="1" value="' . esc_attr( (string) $val ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'How long a signed URL remains valid (minutes). Default: 60.', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render settings field: rate limit toggle.
 *
 * @return void
 */
function thespl_render_streaming_rate_limit_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['streaming_rate_limit_enabled'] );
	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[streaming_rate_limit_enabled]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Enable IP-based rate limiting for the streaming endpoint.', 'the-studio-player' ) . '</span>';
	echo '</label>';
	echo '<p class="thespl-admin-warning thespl-security-warn-rl" style="color:#d63638; font-weight:bold; margin-top:5px; display:' . ( $enabled ? 'none' : 'block' ) . ';">';
	echo '⚠️ ' . esc_html__( 'Warning: Without rate limiting, your server is more vulnerable to automated scraping or excessive resource usage.', 'the-studio-player' );
	echo '</p>';
}

/**
 * Render settings field: rate limit RPM.
 *
 * @return void
 */
function thespl_render_streaming_rate_limit_rpm_field() {
	$settings = thespl_get_player_settings();
	$val      = isset( $settings['streaming_rate_limit_rpm'] ) ? (int) $settings['streaming_rate_limit_rpm'] : 300;
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="number" class="small-text" name="thespl_player_settings[streaming_rate_limit_rpm]" min="10" max="1000" step="10" value="' . esc_attr( (string) $val ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Allowed requests per minute per IP. Recommended: 300+ for Range-requests.', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render settings field: rate limit burst.
 *
 * @return void
 */
function thespl_render_streaming_rate_limit_burst_field() {
	$settings = thespl_get_player_settings();
	$val      = isset( $settings['streaming_rate_limit_burst'] ) ? (int) $settings['streaming_rate_limit_burst'] : 80;
	echo '<div class="thespl-admin-inline-row">';
	echo '<input type="number" class="small-text" name="thespl_player_settings[streaming_rate_limit_burst]" min="5" max="500" step="5" value="' . esc_attr( (string) $val ) . '" />';
	echo '<span class="thespl-admin-help">' . esc_html__( 'Maximum burst of requests allowed in a very short window. Default: 80.', 'the-studio-player' ) . '</span>';
	echo '</div>';
}

/**
 * Render settings field: show security verification toggle.
 *
 * @return void
 */
function thespl_render_player_show_security_verification_field() {
	$settings = thespl_get_player_settings();
	$enabled  = ! empty( $settings['show_security_verification'] );

	echo '<label class="thespl-admin-inline-label">';
	echo '<input type="checkbox" name="thespl_player_settings[show_security_verification]" value="1" ' . checked( $enabled, true, false ) . ' />';
	echo '<span>' . esc_html__( 'Show security verification box on the Muxer-Uploader page.', 'the-studio-player' ) . '</span>';
	echo '</label>';
}

/**
 * Render settings field: plugin access role.
 *
 * This setting controls access to plugin management areas only.
 * Security-sensitive permissions remain administrator-only.
 */
function thespl_render_player_min_capability_field() {
	// ONLY Administrators can see or change this setting to prevent lockout scenarios.
	if ( ! current_user_can( 'manage_options' ) ) {
		echo '<p class="description" style="color:#d63638; font-weight:bold;">' . esc_html__( 'Only administrators can change management permissions.', 'the-studio-player' ) . '</p>';
		return;
	}

	$current = thespl_get_min_capability();

	$roles = array(
		'manage_options'    => __( 'Administrators only', 'the-studio-player' ),
		'edit_others_posts' => __( 'Administrators & Editors (Default)', 'the-studio-player' ),
		'publish_posts'     => __( 'Administrators, Editors & Authors', 'the-studio-player' ),
	);

	// Horizontal line separator (slick design).
	echo '<div style="margin-top: 10px; border-top: 1px solid #c3c4c7; padding-top: 20px;"></div>';

	echo '<select name="thespl_player_settings[min_capability]" id="thespl_player_min_capability" style="width: 100%; max-width: 400px;">';
	foreach ( $roles as $cap => $label ) {
		echo '<option value="' . esc_attr( $cap ) . '" ' . selected( $current, $cap, false ) . '>' . esc_html( $label ) . '</option>';
	}
	echo '</select>';
	echo '<p class="description">' . esc_html__( 'Select the minimum role that can access plugin management pages. Security-critical settings and license management remain administrator-only.', 'the-studio-player' ) . '</p>';
}

/**
 * Render the Player Settings page.
 *
 * @return void
 */
function thespl_render_player_settings_page() {
	if ( ! thespl_current_user_can_policy( 'plugin_access' ) ) {
		return;
	}

	$can_manage_general  = thespl_current_user_can_policy( 'settings_general' );
	$can_manage_security = thespl_current_user_can_policy( 'settings_security' );
	$ver                 = thespl_get_readme_stable_tag_version();
	$plugin_name         = __( 'The Studio Player', 'the-studio-player' );
	$page_label          = __( 'Settings', 'the-studio-player' );
	$page_title          = $plugin_name;
	$profile             = thespl_get_capability_profile();
	$has_pro_build       = isset( $profile['is_pro'] ) ? (bool) $profile['is_pro'] : false;
	if ( '' !== $ver ) {
		$page_title .= ' - ' . $ver;
		if ( $has_pro_build ) {
			$page_title .= ' Pro';
		}
	}
	$page_title .= ' - ' . $page_label;
	?>
	<div class="wrap thespl-admin-wrapper">
		<h1><?php echo esc_html( $page_title ); ?></h1>

		<?php thespl_render_remote_admin_banners(); ?>

		<?php thespl_render_admin_top_nav( 'thespl-player-settings' ); ?>

		<?php settings_errors(); ?>

		<div class="section-box">
			<form method="post" action="options.php">
				<?php settings_fields( 'thespl_player_settings' ); ?>
				
				<div class="thespl-settings-tabs">
					<!-- Tab Radio Buttons -->
					<input type="radio" id="thespl-tab-ui" name="thespl-tab" class="thespl-tab-radio" checked>
					<input type="radio" id="thespl-tab-audio" name="thespl-tab" class="thespl-tab-radio" <?php disabled( $can_manage_general, false ); ?>>
					<input type="radio" id="thespl-tab-muxer" name="thespl-tab" class="thespl-tab-radio" <?php disabled( $can_manage_general, false ); ?>>
					<input type="radio" id="thespl-tab-security" name="thespl-tab" class="thespl-tab-radio" <?php disabled( $can_manage_security, false ); ?>>
					
					<!-- Tab Navigation Bar -->
					<div class="thespl-tabs-bar nav-tab-wrapper" role="tablist">
						<label for="thespl-tab-ui" class="nav-tab"><?php esc_html_e( 'General', 'the-studio-player' ); ?></label>
						<?php if ( $can_manage_general ) : ?>
							<label for="thespl-tab-audio" class="nav-tab"><?php esc_html_e( 'Audio Config', 'the-studio-player' ); ?></label>
						<?php else : ?>
							<span class="nav-tab thespl-admin-nav-tab-disabled" title="<?php echo esc_attr__( 'To gain access, contact your administrator.', 'the-studio-player' ); ?>" aria-disabled="true">
								<span class="thespl-admin-nav-tab-label"><?php esc_html_e( 'Audio Config', 'the-studio-player' ); ?></span>
								<span class="thespl-admin-nav-tab-lock"><?php esc_html_e( '🔒 Editor/Admin', 'the-studio-player' ); ?></span>
							</span>
						<?php endif; ?>
						<?php if ( $can_manage_general ) : ?>
							<label for="thespl-tab-muxer" class="nav-tab"><?php esc_html_e( 'Muxer-Uploader', 'the-studio-player' ); ?></label>
						<?php else : ?>
							<span class="nav-tab thespl-admin-nav-tab-disabled" title="<?php echo esc_attr__( 'To gain access, contact your administrator.', 'the-studio-player' ); ?>" aria-disabled="true">
								<span class="thespl-admin-nav-tab-label"><?php esc_html_e( 'Muxer-Uploader', 'the-studio-player' ); ?></span>
								<span class="thespl-admin-nav-tab-lock"><?php esc_html_e( '🔒 Editor/Admin', 'the-studio-player' ); ?></span>
							</span>
						<?php endif; ?>
						<?php if ( $can_manage_security ) : ?>
							<label for="thespl-tab-security" class="nav-tab"><?php esc_html_e( 'Security', 'the-studio-player' ); ?></label>
						<?php else : ?>
							<span class="nav-tab thespl-admin-nav-tab-disabled" title="<?php echo esc_attr__( 'To gain access, contact your administrator.', 'the-studio-player' ); ?>" aria-disabled="true">
								<span class="thespl-admin-nav-tab-label"><?php esc_html_e( 'Security', 'the-studio-player' ); ?></span>
								<span class="thespl-admin-nav-tab-lock"><?php esc_html_e( '🔒 Admin only', 'the-studio-player' ); ?></span>
							</span>
						<?php endif; ?>
					</div>
					
					<!-- Tab Panels -->
					<div class="thespl-tabs-panels">
						<div class="thespl-tab-panel thespl-tab-panel-ui">
							<table class="form-table" role="presentation"><tbody>
								<?php do_settings_fields( 'thespl-player-settings', 'thespl_player_settings_ui' ); ?>
							</tbody></table>
						</div>
						<div class="thespl-tab-panel thespl-tab-panel-audio">
							<?php if ( $can_manage_general ) : ?>
								<table class="form-table" role="presentation"><tbody>
									<?php do_settings_fields( 'thespl-player-settings', 'thespl_player_settings_audio' ); ?>
								</tbody></table>
							<?php endif; ?>
						</div>
						<div class="thespl-tab-panel thespl-tab-panel-muxer">
							<?php if ( $can_manage_general ) : ?>
								<table class="form-table" role="presentation"><tbody>
									<?php do_settings_fields( 'thespl-player-settings', 'thespl_player_settings_muxer' ); ?>
								</tbody></table>
							<?php endif; ?>
						</div>
						<div class="thespl-tab-panel thespl-tab-panel-security">
							<?php if ( $can_manage_security ) : ?>
								<table class="form-table" role="presentation"><tbody>
									<?php do_settings_fields( 'thespl-player-settings', 'thespl_player_settings_security' ); ?>
								</tbody></table>
							<?php endif; ?>
						</div>
					</div>
				</div>
				
				<?php submit_button(); ?>
			</form>
		</div>
	</div>
	<?php
}
