<?php
/**
 * Plugin Settings
 *
 * @package KursBooking
 */

declare(strict_types=1);

// Prevent direct access.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Class Kurs_Booking_Settings
 *
 * Handles plugin settings using WordPress Settings API.
 * PHP 8.4 compatible with explicit nullable types and modern syntax.
 */
class Kurs_Booking_Settings {

	/**
	 * Option group name
	 */
	private const OPTION_GROUP = 'kurs_booking_settings';

	/**
	 * Settings page slug
	 */
	private const PAGE_SLUG = 'kurs-booking-settings';

	/**
	 * Available tabs
	 *
	 * @var array<string, string>
	 */
	private static array $tabs = array();

	/**
	 * Initialize hooks
	 */
	public static function init(): void {
		add_action( 'admin_init', array( __CLASS__, 'register_settings' ) );

		// Ensure default booking fields exist (for existing installations).
		self::init_default_booking_fields();

		// Initialize tabs - Kundenreihenfolge.
		self::$tabs = array(
			'general' => __( 'Allgemein', 'kurs-booking' ),
		);

		// Stammdaten (conditional).
		if ( self::is_module_active( 'stammdaten' ) ) {
			self::$tabs['masterdata'] = __( 'Stammdaten', 'kurs-booking' );
		}

		// Finanzen & Rechtliches.
		self::$tabs['bank']  = __( 'Bankverbindung', 'kurs-booking' );
		self::$tabs['legal'] = __( 'Rechtliches', 'kurs-booking' );

		// Stornierung (conditional).
		if ( self::is_module_active( 'stornierung' ) ) {
			self::$tabs['cancellation'] = __( 'Stornierung', 'kurs-booking' );
		}

		// Zahlungen & Buchung.
		self::$tabs['payments'] = __( 'Zahlungen', 'kurs-booking' );
		self::$tabs['booking']  = __( 'Buchung', 'kurs-booking' );
		self::$tabs['fields']   = __( 'Buchungsfelder', 'kurs-booking' );
		self::$tabs['prices']   = __( 'Preise & MwSt', 'kurs-booking' );

		// sevDesk (conditional).
		if ( self::is_module_active( 'sevdesk' ) ) {
			self::$tabs['sevdesk'] = __( 'sevDesk', 'kurs-booking' );
		}

		// E-Mails.
		self::$tabs['emails']          = __( 'E-Mails', 'kurs-booking' );
		self::$tabs['email_templates'] = __( 'E-Mail Vorlagen', 'kurs-booking' );

		// Video (conditional).
		if ( self::is_module_active( 'videos' ) ) {
			self::$tabs['video'] = __( 'Video-Service', 'kurs-booking' );
		}

		// Import, Module, Dienstleistungen, Spam, Portal.
		self::$tabs['import']           = __( 'MEC Import', 'kurs-booking' );
		self::$tabs['modules']          = __( 'Module', 'kurs-booking' );
		self::$tabs['dienstleistungen'] = __( 'Dienstleistungen', 'kurs-booking' );
		self::$tabs['spam']             = __( 'Spam-Schutz', 'kurs-booking' );
		self::$tabs['portal']           = __( 'Kundenportal', 'kurs-booking' );
	}

	/**
	 * Register all settings
	 */
	public static function register_settings(): void {
		// General settings.
		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_name',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_street',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_city',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_phone',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_email',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_email',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_website',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'esc_url_raw',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_company_ceo',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_tax_number',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_vat_id',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => '',
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_logo',
			array(
				'type'              => 'integer',
				'sanitize_callback' => 'absint',
				'default'           => 0,
			)
		);

		// Custom booking fields (JSON stored).
		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_custom_fields',
			array(
				'type'              => 'string',
				'sanitize_callback' => array( __CLASS__, 'sanitize_custom_fields' ),
				'default'           => '[]',
			)
		);

		// Email settings.
		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_email_from_name',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_text_field',
				'default'           => get_bloginfo( 'name' ),
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_email_from_address',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_email',
				'default'           => get_option( 'admin_email' ),
			)
		);

		register_setting(
			self::OPTION_GROUP,
			'kurs_booking_email_bcc',
			array(
				'type'              => 'string',
				'sanitize_callback' => 'sanitize_email',
				'default'           => '',
			)
		);

		// Tab 2: Buchung.
		register_setting( self::OPTION_GROUP, 'kurs_booking_default_ticket_name', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'Ticket' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_number_prefix', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'BK' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_next_number', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 1 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_confirm_validity_hours', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 48 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_admin_email', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_email', 'default' => get_option( 'admin_email' ) ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_bcc_admin', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_max_tickets', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 10 ) );

		// Tab 3: Preise & MwSt.
		register_setting( self::OPTION_GROUP, 'kurs_booking_price_display', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'gross' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_vat_rate', array( 'type' => 'number', 'sanitize_callback' => 'floatval', 'default' => 19.0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_small_business', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_currency_symbol', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '€' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_currency_position', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'after' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_decimal_separator', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => ',' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_thousand_separator', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '.' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_decimals', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 2 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_default_deposit_percent', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_manual_payment_hint', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => 'Wird vor Ort verrechnet' ) );

		// Tab 4: Stornierung.
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_free_days', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 28 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_partial_days', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 14 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_partial_percent', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 50 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_custom_text', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_deposit_retained', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '1' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_cancel_allow_replacement', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '1' ) );

		// Tab 5: Rechtliches.
		register_setting( self::OPTION_GROUP, 'kurs_booking_agb_page_id', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_privacy_page_id', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_withdrawal_notice', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_agb_checkbox_text', array( 'type' => 'string', 'sanitize_callback' => 'wp_kses_post', 'default' => '' ) );

		// Tab 8: Bankverbindung.
		register_setting( self::OPTION_GROUP, 'kurs_booking_bank_account_holder', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_bank_iban', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_bank_bic', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_bank_name', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );

		// Tab 9: Zahlungen.
		register_setting( self::OPTION_GROUP, 'kurs_booking_gateway_invoice', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_gateway_paypal', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_gateway_stripe', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false ) );

		// Tab 10: Spam-Schutz (Multi-Layer).
		// Layer 1: Cloudflare Turnstile.
		register_setting( self::OPTION_GROUP, 'kurs_booking_turnstile_enabled', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => false ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_turnstile_site_key', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_turnstile_secret_key', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_turnstile_theme', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_key', 'default' => 'auto' ) );
		// Layer 2: Honeypot + Time-based.
		register_setting( self::OPTION_GROUP, 'kurs_booking_spam_honeypot', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_spam_min_time', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 3 ) );
		// Layer 3: Content filtering.
		register_setting( self::OPTION_GROUP, 'kurs_booking_spam_content_filter', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_spam_max_urls', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 2 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_spam_keywords', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_textarea_field', 'default' => '' ) );

		// Tab 11: sevDesk.
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_api_token', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '' ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_contact_category', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_auto_invoice', array( 'type' => 'boolean', 'sanitize_callback' => 'rest_sanitize_boolean', 'default' => true ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_invoice_status', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 100 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_user_id', array( 'type' => 'integer', 'sanitize_callback' => 'absint', 'default' => 0 ) );
		register_setting( self::OPTION_GROUP, 'kurs_booking_sevdesk_position_text', array( 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'default' => '{kurs_name} (Buchung: {buchungs_nummer})' ) );

		// Add settings sections.
		add_settings_section(
			'kurs_booking_company_section',
			__( 'Firmenangaben', 'kurs-booking' ),
			array( __CLASS__, 'render_company_section' ),
			self::PAGE_SLUG
		);
	}

	/**
	 * Sanitize custom fields JSON
	 *
	 * @param mixed $input The input value.
	 * @return string Sanitized JSON string.
	 */
	public static function sanitize_custom_fields( mixed $input ): string {
		if ( ! is_string( $input ) ) {
			return '[]';
		}

		$fields = json_decode( $input, true );

		if ( ! is_array( $fields ) ) {
			return '[]';
		}

		$sanitized = array();
		$allowed_types = array( 'text', 'email', 'tel', 'number', 'date', 'textarea', 'select', 'radio', 'checkbox', 'file', 'agreement', 'p', 'name', 'address', 'plz', 'city', 'country', 'iban', 'url' );

		foreach ( $fields as $field ) {
			if ( ! is_array( $field ) ) {
				continue;
			}

			$type = sanitize_key( $field['type'] ?? 'text' );
			if ( ! in_array( $type, $allowed_types, true ) ) {
				$type = 'text';
			}

			$sanitized_field = array(
				'type'        => $type,
				'label'       => sanitize_text_field( $field['label'] ?? '' ),
				'placeholder' => sanitize_text_field( $field['placeholder'] ?? '' ),
				'mandatory'   => (bool) ( $field['mandatory'] ?? false ),
				'condition'   => sanitize_text_field( $field['condition'] ?? '' ),
				'page'        => absint( $field['page'] ?? 0 ),
			);

			// Handle options for select/radio.
			if ( in_array( $type, array( 'select', 'radio' ), true ) && ! empty( $field['options'] ) ) {
				$sanitized_field['options'] = array_map( 'sanitize_text_field', (array) $field['options'] );
			}

			// Handle agreement link/page.
			if ( 'agreement' === $type && ! empty( $field['link'] ) ) {
				$sanitized_field['link'] = esc_url_raw( $field['link'] );
			}

			$sanitized[] = $sanitized_field;
		}

		return wp_json_encode( $sanitized ) ?: '[]';
	}

	/**
	 * Render company section description
	 */
	public static function render_company_section(): void {
		echo '<p>' . esc_html__( 'Diese Angaben werden im Footer aller E-Mails angezeigt (rechtlich erforderlich).', 'kurs-booking' ) . '</p>';
	}

	/**
	 * Render the settings page
	 */
	public static function render_settings_page(): void {
		if ( ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'Keine Berechtigung.', 'kurs-booking' ) );
		}

		// Get current tab.
		$current_tab = isset( $_GET['tab'] ) ? sanitize_key( $_GET['tab'] ) : 'general';
		if ( ! array_key_exists( $current_tab, self::$tabs ) ) {
			$current_tab = 'general';
		}

		// Handle form submission.
		$settings_saved = false;
		if ( isset( $_POST['kurs_booking_settings_nonce'] ) &&
			 wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['kurs_booking_settings_nonce'] ) ), 'kurs_booking_save_settings' ) ) {
			self::save_settings( $current_tab );
			$settings_saved = true;
		}
		?>
		<div class="wrap">
			<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>

			<?php if ( $settings_saved ) : ?>
				<div class="notice notice-success is-dismissible">
					<p><?php esc_html_e( 'Einstellungen gespeichert.', 'kurs-booking' ); ?></p>
				</div>
			<?php endif; ?>

			<nav class="nav-tab-wrapper">
				<?php foreach ( self::$tabs as $tab_key => $tab_label ) : ?>
					<a href="<?php echo esc_url( add_query_arg( 'tab', $tab_key ) ); ?>"
					   class="nav-tab <?php echo $current_tab === $tab_key ? 'nav-tab-active' : ''; ?>">
						<?php echo esc_html( $tab_label ); ?>
					</a>
				<?php endforeach; ?>
			</nav>

			<form method="post" action="" class="kurs-booking-settings-form">
				<?php wp_nonce_field( 'kurs_booking_save_settings', 'kurs_booking_settings_nonce' ); ?>

				<div class="kurs-booking-settings-content">
					<?php
					match ( $current_tab ) {
						'general'          => self::render_general_tab(),
						'modules'          => self::render_modules_tab(),
						'masterdata'       => self::render_masterdata_tab(),
						'booking'          => self::render_booking_tab(),
						'prices'           => self::render_prices_tab(),
						'cancellation'     => self::render_cancellation_tab(),
						'legal'            => self::render_legal_tab(),
						'fields'           => self::render_fields_tab(),
						'emails'           => self::render_emails_tab(),
						'bank'             => self::render_bank_tab(),
						'payments'         => self::render_payments_tab(),
						'spam'             => self::render_spam_tab(),
						'sevdesk'          => self::render_sevdesk_tab(),
						'video'            => self::render_video_tab(),
						'email_templates'  => self::render_email_templates_tab(),
						'import'           => self::render_import_tab(),
						'portal'           => self::render_portal_tab(),
						'dienstleistungen' => self::render_dienstleistungen_tab(),
						default            => self::render_general_tab(),
					};
		?>
				</div>

				<div class="kurs-booking-sticky-footer">
					<?php
					$dienstleistungen = Kurs_Booking_Dienstleistungen::get_all();
					?>
					<div class="kurs-booking-global-filter<?php echo 'fields' === $current_tab ? ' visible' : ''; ?>">
						<label for="kurs-booking-field-filter" class="kurs-booking-filter-label">
							<?php esc_html_e( 'Felder filtern:', 'kurs-booking' ); ?>
						</label>
						<span class="kurs-booking-filter-badge" data-filter="alle" style="background-color: #4CAF50;"></span>
						<select id="kurs-booking-field-filter" class="kurs-booking-global-filter-select">
							<option value="alle" data-color="#4CAF50"><?php esc_html_e( 'Alle Felder', 'kurs-booking' ); ?></option>
							<?php foreach ( $dienstleistungen as $id => $dl ) : ?>
								<option value="<?php echo esc_attr( $id ); ?>" data-color="<?php echo esc_attr( $dl['badge_color'] ?? '#666' ); ?>">
									<?php echo esc_html( $dl['name'] ?? $id ); ?>
								</option>
							<?php endforeach; ?>
						</select>
						<span class="kurs-booking-filter-count"></span>
					</div>
					<div class="kurs-booking-footer-save">
						<?php submit_button( __( 'Einstellungen speichern', 'kurs-booking' ) ); ?>
					</div>
				</div>
			</form>
		</div>
		<?php
	}

	/**
	 * Render general settings tab
	 */
	private static function render_general_tab(): void {
		$logo_id = (int) get_option( 'kurs_booking_logo', 0 );
		?>
		<h2><?php esc_html_e( 'Firmenangaben (für E-Mail-Footer)', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Diese Angaben sind für rechtskonforme E-Mails erforderlich.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_logo"><?php esc_html_e( 'Logo', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<div class="kurs-booking-logo-upload">
						<?php if ( $logo_id ) : ?>
							<div class="kurs-booking-logo-preview">
								<?php echo wp_get_attachment_image( $logo_id, 'medium' ); ?>
							</div>
						<?php endif; ?>
						<input type="hidden" name="kurs_booking_logo" id="kurs_booking_logo" value="<?php echo esc_attr( (string) $logo_id ); ?>">
						<button type="button" class="button" id="kurs-booking-upload-logo">
							<?php esc_html_e( 'Logo auswählen', 'kurs-booking' ); ?>
						</button>
						<?php if ( $logo_id ) : ?>
							<button type="button" class="button" id="kurs-booking-remove-logo">
								<?php esc_html_e( 'Entfernen', 'kurs-booking' ); ?>
							</button>
						<?php endif; ?>
					</div>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_name"><?php esc_html_e( 'Firmenname', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="text" name="kurs_booking_company_name" id="kurs_booking_company_name"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_name', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_street"><?php esc_html_e( 'Straße', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="text" name="kurs_booking_company_street" id="kurs_booking_company_street"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_street', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_city"><?php esc_html_e( 'PLZ Ort', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="text" name="kurs_booking_company_city" id="kurs_booking_company_city"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_city', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_phone"><?php esc_html_e( 'Telefon', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="tel" name="kurs_booking_company_phone" id="kurs_booking_company_phone"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_phone', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_email"><?php esc_html_e( 'E-Mail', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="email" name="kurs_booking_company_email" id="kurs_booking_company_email"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_email', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_website"><?php esc_html_e( 'Website', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="url" name="kurs_booking_company_website" id="kurs_booking_company_website"
						   value="<?php echo esc_url( get_option( 'kurs_booking_company_website', '' ) ); ?>"
						   class="regular-text" placeholder="https://">.
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_company_ceo"><?php esc_html_e( 'Geschäftsführer/Inhaber', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="text" name="kurs_booking_company_ceo" id="kurs_booking_company_ceo"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_company_ceo', '' ) ); ?>"
						   class="regular-text" required>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_tax_number"><?php esc_html_e( 'Steuernummer', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_tax_number" id="kurs_booking_tax_number"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_tax_number', '' ) ); ?>"
						   class="regular-text">
					<p class="description"><?php esc_html_e( 'Steuernummer ODER USt-IdNr. ist Pflicht.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_vat_id"><?php esc_html_e( 'USt-IdNr.', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_vat_id" id="kurs_booking_vat_id"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_vat_id', '' ) ); ?>"
						   class="regular-text" placeholder="DE123456789">
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render modules tab
	 */
	private static function render_modules_tab(): void {
		$modules = get_option( 'kurs_booking_modules', array() );

		// Default all modules to enabled if not set.
		$defaults = array(
			// Basis-Module (immer aktiv, nicht deaktivierbar).
			'kurse'              => true,
			'buchungen'          => true,
			'email_system'       => true,
			// Feature-Module.
			'videos'             => true,
			'sevdesk'            => true,
			'stornierung'        => true,
			'kurs_vorlagen'      => true,
			'stammdaten'         => true,
			'preisvarianten'     => true,
			'varianten_zusatz'   => true,
			'bedingte_felder'    => true,
			'widerrufsrecht'     => true,
			'related_kurse'      => true,
			'show_category'      => true,
		);

		$modules = wp_parse_args( $modules, $defaults );
		?>
		<h2><?php esc_html_e( 'Basis-Module', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Diese Module sind für den Grundbetrieb erforderlich und können nicht deaktiviert werden.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Kurse', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" checked disabled>
						<?php esc_html_e( 'Post-Type für Kurse/Veranstaltungen', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Basis-Modul - immer aktiv', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Buchungen', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" checked disabled>
						<?php esc_html_e( 'Buchungsverwaltung und Buchungsformular', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Basis-Modul - immer aktiv', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'E-Mail-System', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" checked disabled>
						<?php esc_html_e( 'Buchungsbestätigungen und Benachrichtigungen', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Basis-Modul - immer aktiv', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>

		<hr style="margin: 30px 0;">

		<h2><?php esc_html_e( 'Feature-Module', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Aktivieren oder deaktivieren Sie optionale Funktionen nach Bedarf.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Video-Kurse', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[videos]" value="1"
							   <?php checked( ! empty( $modules['videos'] ) ); ?>>
						<?php esc_html_e( 'Video Post-Type und Video-Zugang für Käufer', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Ermöglicht digitale Video-Kurse (Produktart E).', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'sevDesk Integration', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[sevdesk]" value="1"
							   <?php checked( ! empty( $modules['sevdesk'] ) ); ?>>
						<?php esc_html_e( 'Automatische Rechnungserstellung in sevDesk', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Erstellt Kontakte und Rechnungen automatisch nach Buchungsbestätigung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Stornierung', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[stornierung]" value="1"
							   <?php checked( ! empty( $modules['stornierung'] ) ); ?>>
						<?php esc_html_e( 'Kunden-Stornierung per Link und Admin-Stornierung', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Stornogebühren-Berechnung basierend auf Fristen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Kurs-Vorlagen', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[kurs_vorlagen]" value="1"
							   <?php checked( ! empty( $modules['kurs_vorlagen'] ) ); ?>>
						<?php esc_html_e( 'Kurse als Vorlage speichern und wiederverwenden', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Für wiederkehrende Kurse mit gleichen Einstellungen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Stammdaten', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[stammdaten]" value="1"
							   <?php checked( ! empty( $modules['stammdaten'] ) ); ?>>
						<?php esc_html_e( 'Verwaltung von Reitlehrern, Pferden und Orten', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Zentrale Listen für Dropdowns in der Kurs-Bearbeitung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Flexible Preisvarianten', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[preisvarianten]" value="1"
							   <?php checked( ! empty( $modules['preisvarianten'] ) ); ?>>
						<?php esc_html_e( 'Mehrere Ticket-Varianten pro Kurs', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Pro-Tag-Berechnung, Auto-Rechnung, manuelle Zahlung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Varianten-Zusatzfelder', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[varianten_zusatz]" value="1"
							   <?php checked( ! empty( $modules['varianten_zusatz'] ) ); ?>>
						<?php esc_html_e( 'Mengen- oder Info-Felder pro Preisvariante', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'z.B. "Anzahl Gastboxen" oder "Pferdename" bei Buchung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Bedingte Buchungsfelder', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[bedingte_felder]" value="1"
							   <?php checked( ! empty( $modules['bedingte_felder'] ) ); ?>>
						<?php esc_html_e( 'Felder basierend auf anderen Feldwerten ein-/ausblenden', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'z.B. "Anzahl Boxen" nur wenn "Gastbox benötigt" aktiviert.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Widerrufsrecht', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[widerrufsrecht]" value="1"
							   <?php checked( ! empty( $modules['widerrufsrecht'] ) ); ?>>
						<?php esc_html_e( 'Widerrufsverzicht-Checkbox für digitale Produkte', 'kurs-booking' ); ?>
					</label>
					<p class="description">
						<?php esc_html_e( 'Rechtskonforme Checkbox gemäß §356 Abs. 5 BGB für Video-Kurse.', 'kurs-booking' ); ?>
						<br>
						<strong style="color: #d63638;"><?php esc_html_e( 'Hinweis:', 'kurs-booking' ); ?></strong>
						<?php esc_html_e( 'Bei digitalen Produkten (Video-Kurse) ist diese Checkbox rechtlich erforderlich!', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Ähnliche Kurse', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[related_kurse]" value="1"
							   <?php checked( ! empty( $modules['related_kurse'] ) ); ?>>
						<?php esc_html_e( 'Ähnliche Kurse auf Kurs-Detailseiten anzeigen', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Zeigt verwandte Kurse aus derselben Kategorie oder manuell ausgewählte Kurse.', 'kurs-booking' ); ?></p>
					<br>
					<label>
						<?php esc_html_e( 'Titel:', 'kurs-booking' ); ?>
						<input type="text" name="kurs_booking_modules[related_kurse_title]"
							   value="<?php echo esc_attr( $modules['related_kurse_title'] ?? __( 'Ähnliche Kurse', 'kurs-booking' ) ); ?>"
							   class="regular-text" placeholder="<?php esc_attr_e( 'Ähnliche Kurse', 'kurs-booking' ); ?>">
					</label>
				</td>
			</tr>
			<tr>
				<th scope="row"><?php esc_html_e( 'Kategorie-Anzeige', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_modules[show_category]" value="1"
							   <?php checked( ! empty( $modules['show_category'] ) ); ?>>
						<?php esc_html_e( 'Kategorie auf Kurs-Cards anzeigen', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Zeigt die Kurs-Kategorie (Taxonomie) auf den Kurs-Karten an.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render custom fields tab
	 */
	private static function render_fields_tab(): void {
		$fields_data = get_option( 'kurs_booking_custom_fields', '[]' );
		if ( is_array( $fields_data ) ) {
			$fields = $fields_data;
		} elseif ( ! empty( $fields_data ) && is_string( $fields_data ) ) {
			$fields = json_decode( $fields_data, true ) ?: array();
		} else {
			$fields = array();
		}
		?>
		<h2><?php esc_html_e( 'Zusätzliche Buchungsfelder', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Definieren Sie zusätzliche Felder, die im Buchungsformular angezeigt werden.', 'kurs-booking' ); ?>
		</p>

		<div id="kurs-booking-fields-container">
			<?php if ( ! empty( $fields ) ) : ?>
				<?php foreach ( $fields as $index => $field ) : ?>
					<?php self::render_field_row( $index, $field ); ?>
				<?php endforeach; ?>
			<?php endif; ?>
		</div>

		<button type="button" class="button" id="kurs-booking-add-field">
			<?php esc_html_e( '+ Feld hinzufügen', 'kurs-booking' ); ?>
		</button>

		<template id="kurs-booking-field-template">
			<?php self::render_field_row( '__INDEX__', array() ); ?>
		</template>
		<?php
	}

	/**
	 * Render a single custom field row
	 *
	 * @param int|string           $index Index or placeholder.
	 * @param array<string, mixed> $field Field data.
	 */
	private static function render_field_row( int|string $index, array $field ): void {
		$type        = $field['type'] ?? 'text';
		$label       = $field['label'] ?? '';
		$placeholder = $field['placeholder'] ?? '';
		$mandatory   = $field['mandatory'] ?? false;
		$options     = $field['options'] ?? array();
		$condition   = $field['condition'] ?? '';
		$page        = $field['page'] ?? '';
		$field_name  = $field['name'] ?? sanitize_key( $label );
		$active      = $field['active'] ?? true;
		$half_width    = $field['half_width'] ?? false;
		$width         = $field['width'] ?? '';
		$basis_field   = $field['basis_field'] ?? false;
		$produktarten  = $field['produktarten'] ?? array();
		?>
		<div class="kurs-booking-field-row <?php echo $active ? '' : 'kurs-booking-field-inactive'; ?>" data-index="<?php echo esc_attr( (string) $index ); ?>">
			<div class="kurs-booking-field-header">
				<div class="kurs-booking-field-header-left">
					<span class="dashicons dashicons-move"></span>
					<label class="kurs-booking-field-active-toggle" title="<?php esc_attr_e( 'Feld aktivieren/deaktivieren', 'kurs-booking' ); ?>">
						<input type="checkbox"
							   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][active]"
							   value="1"
							   class="kurs-booking-field-active-checkbox"
							   <?php checked( $active ); ?>>
						<span class="kurs-booking-toggle-slider"></span>
					</label>
					<span class="kurs-booking-field-title">
						<?php echo esc_html( $label ?: __( 'Neues Feld', 'kurs-booking' ) ); ?>
					</span>
					<?php
					// Sprint 8.2: Produktart-Badges im Header anzeigen.
					if ( $basis_field ) :
						?>
						<span class="kurs-booking-field-type-badge kurs-booking-field-type-basis" title="<?php esc_attr_e( 'Wird bei allen Produktarten angezeigt', 'kurs-booking' ); ?>">
							<span class="kurs-booking-badge-dot" style="background-color: #666;"></span>
							<?php esc_html_e( 'Basis', 'kurs-booking' ); ?>
						</span>
						<?php
					elseif ( ! empty( $produktarten ) ) :
						// Zeige die zugewiesenen Produktarten.
						$all_dienstleistungen = array();
						if ( class_exists( 'Kurs_Booking_Dienstleistungen' ) ) {
							$all_dienstleistungen = Kurs_Booking_Dienstleistungen::get_all();
						}
						foreach ( $produktarten as $pa_id ) :
							$pa = $all_dienstleistungen[ $pa_id ] ?? null;
							if ( $pa ) :
								?>
								<span class="kurs-booking-field-type-badge" title="<?php echo esc_attr( ( $pa['label'] ?? '' ) . ' ' . ( $pa['name'] ?? '' ) ); ?>">
									<span class="kurs-booking-badge-dot" style="background-color: <?php echo esc_attr( $pa['badge_color'] ?? '#999' ); ?>;"></span>
									<?php echo esc_html( $pa['name'] ?? $pa_id ); ?>
								</span>
								<?php
							endif;
						endforeach;
					else :
						// Keine Einschränkung = alle Produktarten.
						?>
						<span class="kurs-booking-field-type-badge kurs-booking-field-type-all" title="<?php esc_attr_e( 'Wird bei allen Produktarten angezeigt', 'kurs-booking' ); ?>">
							<span class="kurs-booking-badge-dot" style="background-color: #4CAF50;"></span>
							<?php esc_html_e( 'Alle', 'kurs-booking' ); ?>
						</span>
						<?php
					endif;
					?>
				</div>
				<code class="kurs-booking-field-name-badge"
					  data-fieldname="<?php echo esc_attr( $field_name ); ?>"
					  title="<?php esc_attr_e( 'Klicken zum Kopieren', 'kurs-booking' ); ?>"
					  style="cursor: pointer;"><?php echo esc_html( $field_name ); ?></code>
				<div class="kurs-booking-field-actions">
					<button type="button" class="kurs-booking-remove-field">
						<?php esc_html_e( 'Entfernen', 'kurs-booking' ); ?>
					</button>
				</div>
			</div>

			<div class="kurs-booking-field-content">
				<div class="kurs-booking-field-grid">
					<div>
						<label><?php esc_html_e( 'Feldtyp', 'kurs-booking' ); ?></label>
						<select name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][type]" class="kurs-booking-field-type">
							<?php
							$types = array(
								// Basis-Typen.
								'text'      => __( 'Text (frei)', 'kurs-booking' ),
								'email'     => __( 'E-Mail', 'kurs-booking' ),
								'tel'       => __( 'Telefon', 'kurs-booking' ),
								'number'    => __( 'Zahl', 'kurs-booking' ),
								'date'      => __( 'Datum', 'kurs-booking' ),
								'textarea'  => __( 'Textbereich', 'kurs-booking' ),
								// Spezifische Typen mit Validierung.
								'name'      => __( 'Name (nur Buchstaben)', 'kurs-booking' ),
								'address'   => __( 'Adresse', 'kurs-booking' ),
								'plz'       => __( 'PLZ (nur Zahlen, 4-5 Stellen)', 'kurs-booking' ),
								'city'      => __( 'Ort (nur Buchstaben)', 'kurs-booking' ),
								'country'   => __( 'Land', 'kurs-booking' ),
								'iban'      => __( 'IBAN', 'kurs-booking' ),
								'url'       => __( 'Website/URL', 'kurs-booking' ),
								// Auswahl-Typen.
								'select'    => __( 'Dropdown', 'kurs-booking' ),
								'radio'     => __( 'Optionsfelder', 'kurs-booking' ),
								'checkbox'  => __( 'Checkbox', 'kurs-booking' ),
								'agreement' => __( 'Zustimmung (mit Link)', 'kurs-booking' ),
								'p'         => __( 'Info-Text', 'kurs-booking' ),
							);
							foreach ( $types as $value => $text ) :
								?>
								<option value="<?php echo esc_attr( $value ); ?>" <?php selected( $type, $value ); ?>>
									<?php echo esc_html( $text ); ?>
								</option>
							<?php endforeach; ?>
						</select>
					</div>

					<div>
						<label><?php esc_html_e( 'Feldname', 'kurs-booking' ); ?></label>
						<textarea name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][label]"
							   rows="3"
							   class="kurs-booking-field-label"><?php echo esc_textarea( $label ); ?></textarea>
					</div>

					<div>
						<label><?php esc_html_e( 'Platzhalter', 'kurs-booking' ); ?></label>
						<input type="text"
							   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][placeholder]"
							   value="<?php echo esc_attr( $placeholder ); ?>">
					</div>

					<div class="kurs-booking-field-checkboxes">
						<label style="display: flex; align-items: center; gap: 4px;">
							<input type="checkbox"
								   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][mandatory]"
								   value="1"
								   style="width: 14px !important; height: 14px !important; margin: 0 !important;"
								   <?php checked( $mandatory ); ?>>
							<span><?php esc_html_e( 'Pflichtfeld', 'kurs-booking' ); ?></span>
						</label>
						<label title="<?php esc_attr_e( 'Basis-Felder werden bei allen Produktarten angezeigt', 'kurs-booking' ); ?>" style="display: flex; align-items: center; gap: 4px;">
							<input type="hidden" name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][basis_field]" value="0">
							<input type="checkbox"
								   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][basis_field]"
								   value="1"
								   class="kurs-booking-basis-field-checkbox"
								   style="width: 14px !important; height: 14px !important; margin: 0 !important;"
								   <?php checked( $basis_field ); ?>>
							<span><?php esc_html_e( 'Basis-Feld', 'kurs-booking' ); ?></span>
							<span class="dashicons dashicons-info" style="font-size: 14px; width: 14px; height: 14px; color: #2271b1;" title="<?php esc_attr_e( 'Wird bei ALLEN Produktarten angezeigt', 'kurs-booking' ); ?>"></span>
						</label>
					</div>
				</div>

				<div class="kurs-booking-field-options" style="<?php echo in_array( $type, array( 'select', 'radio' ), true ) ? '' : 'display:none;'; ?>">
					<label><?php esc_html_e( 'Optionen (kommagetrennt)', 'kurs-booking' ); ?></label>
					<?php
					// Handle both string and array options.
					$options_text = is_array( $options ) ? implode( ', ', $options ) : (string) $options;
					?>
					<input type="text"
						   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][options]"
						   value="<?php echo esc_attr( $options_text ); ?>"
						   placeholder="<?php esc_attr_e( 'Option 1, Option 2, Option 3', 'kurs-booking' ); ?>"
						   class="large-text">
				</div>

				<div class="kurs-booking-field-footer">
					<button type="button" class="kurs-booking-options-btn" title="<?php esc_attr_e( 'Erweiterte Optionen', 'kurs-booking' ); ?>">
						<span class="dashicons dashicons-admin-generic"></span>
						<?php esc_html_e( 'Optionen', 'kurs-booking' ); ?>
					</button>

					<div class="kurs-booking-options-popup">
						<div class="kurs-booking-options-popup-content">
							<div class="kurs-booking-options-popup-header">
								<strong><?php esc_html_e( 'Erweiterte Optionen', 'kurs-booking' ); ?></strong>
								<button type="button" class="kurs-booking-options-close">&times;</button>
							</div>
							<?php if ( self::is_module_active( 'bedingte_felder' ) ) : ?>
							<div class="kurs-booking-options-row">
								<label><?php esc_html_e( 'Nur anzeigen wenn', 'kurs-booking' ); ?></label>
								<input type="text"
									   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][condition]"
									   value="<?php echo esc_attr( $condition ); ?>"
									   placeholder="<?php esc_attr_e( 'feldname:ja', 'kurs-booking' ); ?>">
								<p class="description"><?php esc_html_e( 'Format: feldname:wert', 'kurs-booking' ); ?></p>
							</div>
							<?php endif; ?>
							<div class="kurs-booking-options-row kurs-booking-field-page-option" style="<?php echo 'agreement' === $type ? '' : 'display:none;'; ?>">
								<label><?php esc_html_e( 'Verlinkte Seite', 'kurs-booking' ); ?></label>
								<?php
								wp_dropdown_pages(
									array(
										'name'              => 'kurs_booking_fields[' . esc_attr( (string) $index ) . '][page]',
										'selected'          => (int) $page,
										'show_option_none'  => esc_html__( '— Keine Seite —', 'kurs-booking' ),
										'option_none_value' => '',
									)
								);
								?>
								<p class="description"><?php esc_html_e( 'Seite für %s Link im Label', 'kurs-booking' ); ?></p>
							</div>
							<div class="kurs-booking-options-row-inline">
								<div class="kurs-booking-options-row">
									<label>
										<input type="hidden" name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][half_width]" value="0">
										<input type="checkbox"
											   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][half_width]"
											   value="1"
											   class="kurs-booking-half-width-checkbox"
											   <?php checked( $half_width ); ?>>
										<?php esc_html_e( '2-spaltig (50%)', 'kurs-booking' ); ?>
									</label>
								</div>
								<div class="kurs-booking-options-row kurs-booking-width-row">
									<label><?php esc_html_e( 'Breite %', 'kurs-booking' ); ?></label>
									<input type="number"
										   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][width]"
										   value="<?php echo esc_attr( (string) $width ); ?>"
										   placeholder="100"
										   step="5"
										   class="kurs-booking-width-input">
								</div>
							</div>

							<!-- Sprint 8.2: Produktarten-Matrix -->
							<div class="kurs-booking-options-row kurs-booking-produktarten-row" style="<?php echo $basis_field ? 'display:none;' : ''; ?>">
								<label><?php esc_html_e( 'Nur bei Produktarten', 'kurs-booking' ); ?></label>
								<div class="kurs-booking-produktarten-matrix">
									<?php
									$all_dienstleistungen = array();
									if ( class_exists( 'Kurs_Booking_Dienstleistungen' ) ) {
										$all_dienstleistungen = Kurs_Booking_Dienstleistungen::get_all();
									}
									if ( ! empty( $all_dienstleistungen ) ) :
										foreach ( $all_dienstleistungen as $dl ) :
											$dl_id      = $dl['id'] ?? '';
											$dl_label   = $dl['label'] ?? '';
											$dl_name    = $dl['name'] ?? '';
											$dl_active  = $dl['active'] ?? true;
											$is_checked = empty( $produktarten ) || in_array( $dl_id, $produktarten, true );
											if ( ! $dl_active ) {
												continue;
											}
											?>
											<label class="kurs-booking-produktart-checkbox" title="<?php echo esc_attr( $dl_label . ' ' . $dl_name ); ?>">
												<input type="checkbox"
													   name="kurs_booking_fields[<?php echo esc_attr( (string) $index ); ?>][produktarten][]"
													   value="<?php echo esc_attr( $dl_id ); ?>"
													   <?php checked( $is_checked ); ?>>
												<span class="kurs-booking-produktart-label" style="background-color: <?php echo esc_attr( $dl['badge_color'] ?? '#999' ); ?>;">
													<?php echo esc_html( $dl_name ); ?>
												</span>
											</label>
										<?php endforeach; ?>
									<?php else : ?>
										<p class="description"><?php esc_html_e( 'Keine Dienstleistungen definiert.', 'kurs-booking' ); ?></p>
									<?php endif; ?>
								</div>
								<p class="description"><?php esc_html_e( 'Leer = alle Produktarten. Wählen Sie aus, bei welchen Produktarten dieses Feld angezeigt wird.', 'kurs-booking' ); ?></p>
								<div class="kurs-booking-produktarten-buttons">
									<button type="button" class="button button-small kurs-booking-produktarten-all">
										<?php esc_html_e( 'Alle', 'kurs-booking' ); ?>
									</button>
									<button type="button" class="button button-small kurs-booking-produktarten-none">
										<?php esc_html_e( 'Keine', 'kurs-booking' ); ?>
									</button>
								</div>
							</div>
						</div>
					</div>

					<button type="button" class="kurs-booking-insert-field" title="<?php esc_attr_e( 'Feld darunter einfuegen', 'kurs-booking' ); ?>">
						<span class="dashicons dashicons-plus-alt2"></span>
						<?php esc_html_e( 'Feld hinzufügen', 'kurs-booking' ); ?>
					</button>
				</div>
			</div>
		</div>
		<?php
	}

	/**
	 * Render emails tab
	 */
	private static function render_emails_tab(): void {
		// Check if FluentSMTP is active.
		$fluentsmtp_active = is_plugin_active( 'fluent-smtp/fluent-smtp.php' );
		?>
		<h2><?php esc_html_e( 'E-Mail-Einstellungen', 'kurs-booking' ); ?></h2>

		<?php if ( $fluentsmtp_active ) : ?>
			<div class="notice notice-success inline" style="margin: 0 0 20px 0;">
				<p>
					<span class="dashicons dashicons-yes-alt" style="color: #46b450;"></span>
					<strong><?php esc_html_e( 'FluentSMTP ist aktiv', 'kurs-booking' ); ?></strong> &ndash;
					<?php esc_html_e( 'E-Mails werden über Ihre SMTP-Konfiguration versendet.', 'kurs-booking' ); ?>
					<a href="<?php echo esc_url( admin_url( 'options-general.php?page=fluent-mail#/' ) ); ?>">
						<?php esc_html_e( 'FluentSMTP Einstellungen', 'kurs-booking' ); ?> &rarr;
					</a>
				</p>
			</div>
		<?php else : ?>
			<div class="notice notice-warning inline" style="margin: 0 0 20px 0;">
				<p>
					<span class="dashicons dashicons-email-alt"></span>
					<strong><?php esc_html_e( 'SMTP-Versand empfohlen', 'kurs-booking' ); ?></strong> &ndash;
					<?php esc_html_e( 'Für zuverlässigen E-Mail-Versand empfehlen wir das kostenlose Plugin', 'kurs-booking' ); ?>
					<a href="<?php echo esc_url( admin_url( 'plugin-install.php?s=fluent+smtp&tab=search&type=term' ) ); ?>">
						<strong>FluentSMTP</strong>
					</a>.
					<?php esc_html_e( 'Es unterstützt Gmail, Outlook, SendGrid und viele weitere Provider.', 'kurs-booking' ); ?>
				</p>
			</div>
		<?php endif; ?>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_email_from_name"><?php esc_html_e( 'Absendername', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_email_from_name" id="kurs_booking_email_from_name"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_email_from_name', get_bloginfo( 'name' ) ) ); ?>"
						   class="regular-text">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_email_from_address"><?php esc_html_e( 'Absender-E-Mail', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="email" name="kurs_booking_email_from_address" id="kurs_booking_email_from_address"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_email_from_address', get_option( 'admin_email' ) ) ); ?>"
						   class="regular-text">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_email_bcc"><?php esc_html_e( 'BCC (Kopie an)', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="email" name="kurs_booking_email_bcc" id="kurs_booking_email_bcc"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_email_bcc', '' ) ); ?>"
						   class="regular-text">
					<p class="description"><?php esc_html_e( 'Optional: E-Mail-Adresse, die bei jeder Buchungsbestätigung eine Kopie erhält.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>

		<h2><?php esc_html_e( 'E-Mail-Inhalte', 'kurs-booking' ); ?></h2>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_payment_due_days"><?php esc_html_e( 'Zahlungsziel', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_payment_due_days" id="kurs_booking_payment_due_days"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_payment_due_days', 14 ) ); ?>"
						   class="small-text" min="0" max="90">
					<span><?php esc_html_e( 'Tage', 'kurs-booking' ); ?></span>
					<p class="description"><?php esc_html_e( 'Zahlungsziel in Tagen ab Buchungsdatum. 0 = Sofortige Zahlung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_default_notes"><?php esc_html_e( 'Standard-Hinweise', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<textarea name="kurs_booking_default_notes" id="kurs_booking_default_notes"
							  rows="5" class="large-text"><?php echo esc_textarea( get_option( 'kurs_booking_default_notes', '' ) ); ?></textarea>
					<p class="description"><?php esc_html_e( 'Allgemeine Hinweise, die in jeder Buchungsbestätigung angezeigt werden. Kurs-spezifische Hinweise können pro Veranstaltung ergänzt werden.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render payments tab
	 */
	private static function render_payments_tab(): void {
		?>
		<h2><?php esc_html_e( 'Zahlungsmethoden', 'kurs-booking' ); ?></h2>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Rechnung', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_gateway_invoice" value="1"
							   <?php checked( get_option( 'kurs_booking_gateway_invoice', true ) ); ?>>
						<?php esc_html_e( 'Zahlung per Rechnung aktivieren', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Kunden erhalten eine Rechnung per E-Mail.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'PayPal', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_gateway_paypal" value="1"
							   <?php checked( get_option( 'kurs_booking_gateway_paypal', false ) ); ?>>
						<?php esc_html_e( 'PayPal aktivieren', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Erfordert separate PayPal-Konfiguration (demnächst).', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Stripe', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_gateway_stripe" value="1"
							   <?php checked( get_option( 'kurs_booking_gateway_stripe', false ) ); ?>>
						<?php esc_html_e( 'Stripe (Kreditkarte) aktivieren', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Erfordert separate Stripe-Konfiguration (demnächst).', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render spam protection tab (Multi-Layer)
	 */
	private static function render_spam_tab(): void {
		// Layer 1: Turnstile.
		$turnstile_enabled = get_option( 'kurs_booking_turnstile_enabled', false );
		$site_key          = get_option( 'kurs_booking_turnstile_site_key', '' );
		$secret            = get_option( 'kurs_booking_turnstile_secret_key', '' );
		$theme             = get_option( 'kurs_booking_turnstile_theme', 'auto' );
		// Layer 2: Honeypot.
		$honeypot_enabled  = get_option( 'kurs_booking_spam_honeypot', true );
		$min_time          = get_option( 'kurs_booking_spam_min_time', 3 );
		// Layer 3: Content filter.
		$content_enabled   = get_option( 'kurs_booking_spam_content_filter', true );
		$max_urls          = get_option( 'kurs_booking_spam_max_urls', 2 );
		$custom_keywords   = get_option( 'kurs_booking_spam_keywords', '' );
		?>
		<h2><?php esc_html_e( 'Multi-Layer Spam-Schutz', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Kombinierter Spam-Schutz mit mehreren Ebenen für maximale Sicherheit bei optimaler Benutzerfreundlichkeit.', 'kurs-booking' ); ?>
		</p>

		<div class="notice notice-info inline" style="margin: 15px 0;">
			<p>
				<strong><?php esc_html_e( 'Aktive Schutzebenen:', 'kurs-booking' ); ?></strong><br>
				<?php
				$layers = array();
				if ( $turnstile_enabled && $site_key ) {
					$layers[] = '✅ ' . __( 'Cloudflare Turnstile (Bot-Erkennung)', 'kurs-booking' );
				}
				if ( $honeypot_enabled ) {
					$layers[] = '✅ ' . __( 'Honeypot + Zeit-Prüfung (versteckte Fallen)', 'kurs-booking' );
				}
				if ( $content_enabled ) {
					$layers[] = '✅ ' . __( 'Inhaltsfilter (Spam-Wörter, URLs)', 'kurs-booking' );
				}
				$layers[] = '✅ ' . __( 'Rate-Limiting (max. 10 Anfragen/Stunde/IP)', 'kurs-booking' );

				echo wp_kses( implode( '<br>', $layers ), array( 'br' => array() ) );
				?>
			</p>
		</div>

		<!-- LAYER 1: Cloudflare Turnstile -->
		<h3 style="margin-top: 30px; padding-bottom: 10px; border-bottom: 1px solid #ccc;">
			<?php esc_html_e( 'Layer 1: Cloudflare Turnstile', 'kurs-booking' ); ?>
		</h3>
		<p class="description">
			<?php esc_html_e( 'Unsichtbare Bot-Erkennung ohne CAPTCHAs. Kostenlos bei Cloudflare.', 'kurs-booking' ); ?>
		</p>

		<?php $test_mode = get_option( 'kurs_booking_turnstile_test_mode', false ); ?>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Turnstile aktivieren', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_turnstile_enabled" value="1"
							   <?php checked( $turnstile_enabled ); ?>>
						<?php esc_html_e( 'Cloudflare Turnstile aktivieren', 'kurs-booking' ); ?>
					</label>
					<p class="description">
						<?php
						printf(
							/* translators: %s: Link to Cloudflare Dashboard */
							wp_kses(
								__( 'Schlüssel erhalten Sie kostenlos im %s unter Turnstile.', 'kurs-booking' ),
								array( 'a' => array( 'href' => array(), 'target' => array() ) )
							),
							'<a href="https://dash.cloudflare.com/" target="_blank">Cloudflare Dashboard</a>'
						);
						?>
					</p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Test-Modus', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_turnstile_test_mode" value="1"
							   <?php checked( $test_mode ); ?>>
						<?php esc_html_e( 'Test-Modus aktivieren (Cloudflare Sandbox)', 'kurs-booking' ); ?>
					</label>
					<p class="description">
						<?php esc_html_e( 'Verwendet automatisch Cloudflare Test-Keys. Validierung immer erfolgreich. Vor Go-Live deaktivieren!', 'kurs-booking' ); ?>
					</p>
					<?php if ( $test_mode ) : ?>
					<div style="margin-top: 8px; padding: 8px 12px; background: #fff3cd; border-left: 4px solid #ffc107; font-size: 13px;">
						<strong><?php esc_html_e( 'Test-Modus aktiv!', 'kurs-booking' ); ?></strong>
						<?php esc_html_e( 'Site Key und Secret Key werden ignoriert. Turnstile akzeptiert alle Anfragen.', 'kurs-booking' ); ?>
					</div>
					<?php endif; ?>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_turnstile_site_key"><?php esc_html_e( 'Site Key', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text"
						   id="kurs_booking_turnstile_site_key"
						   name="kurs_booking_turnstile_site_key"
						   value="<?php echo esc_attr( $site_key ); ?>"
						   class="regular-text"
						   placeholder="0x4AAAAAAA...">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_turnstile_secret_key"><?php esc_html_e( 'Secret Key', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="password"
						   id="kurs_booking_turnstile_secret_key"
						   name="kurs_booking_turnstile_secret_key"
						   value="<?php echo esc_attr( $secret ); ?>"
						   class="regular-text"
						   placeholder="0x4AAAAAAA...">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_turnstile_theme"><?php esc_html_e( 'Design', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<select id="kurs_booking_turnstile_theme" name="kurs_booking_turnstile_theme">
						<option value="auto" <?php selected( $theme, 'auto' ); ?>><?php esc_html_e( 'Automatisch', 'kurs-booking' ); ?></option>
						<option value="light" <?php selected( $theme, 'light' ); ?>><?php esc_html_e( 'Hell', 'kurs-booking' ); ?></option>
						<option value="dark" <?php selected( $theme, 'dark' ); ?>><?php esc_html_e( 'Dunkel', 'kurs-booking' ); ?></option>
					</select>
				</td>
			</tr>
		</table>

		<?php if ( $turnstile_enabled && $site_key ) : ?>
		<h4><?php esc_html_e( 'Vorschau', 'kurs-booking' ); ?></h4>
		<div style="padding: 15px; background: #f0f0f1; border-radius: 4px; max-width: 320px; display: inline-block;">
			<div class="cf-turnstile" data-sitekey="<?php echo esc_attr( $site_key ); ?>" data-theme="<?php echo esc_attr( $theme ); ?>"></div>
		</div>
		<?php // phpcs:ignore WordPress.WP.EnqueuedResources.NonEnqueuedScript -- Cloudflare Turnstile requires inline script for preview widget. ?>
		<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>.
		<?php endif; ?>

		<!-- LAYER 2: Honeypot + Time-based -->
		<h3 style="margin-top: 30px; padding-bottom: 10px; border-bottom: 1px solid #ccc;">
			<?php esc_html_e( 'Layer 2: Honeypot & Zeit-Prüfung', 'kurs-booking' ); ?>
		</h3>
		<p class="description">
			<?php esc_html_e( 'Unsichtbare Fallen für Bots – Menschen bemerken nichts davon.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Honeypot aktivieren', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_spam_honeypot" value="1"
							   <?php checked( $honeypot_enabled ); ?>>
						<?php esc_html_e( 'Unsichtbare Honeypot-Felder verwenden', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Bots füllen versteckte Felder aus – echte Benutzer nicht.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_spam_min_time"><?php esc_html_e( 'Mindest-Ausfüllzeit', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number"
						   id="kurs_booking_spam_min_time"
						   name="kurs_booking_spam_min_time"
						   value="<?php echo esc_attr( $min_time ); ?>"
						   min="0"
						   max="30"
						   style="width: 80px;"> <?php esc_html_e( 'Sekunden', 'kurs-booking' ); ?>
					<p class="description"><?php esc_html_e( 'Formulare, die schneller abgeschickt werden, werden blockiert. 0 = deaktiviert.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>

		<!-- LAYER 3: Content Filter -->
		<h3 style="margin-top: 30px; padding-bottom: 10px; border-bottom: 1px solid #ccc;">
			<?php esc_html_e( 'Layer 3: Inhaltsfilter', 'kurs-booking' ); ?>
		</h3>
		<p class="description">
			<?php esc_html_e( 'Prüft Eingaben auf typische Spam-Muster und blockiert verdächtige Inhalte.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Inhaltsfilter aktivieren', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_spam_content_filter" value="1"
							   <?php checked( $content_enabled ); ?>>
						<?php esc_html_e( 'Texte auf Spam-Inhalte prüfen', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Blockiert typische Spam-Begriffe, übermäßige URLs und kyrillische Zeichen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_spam_max_urls"><?php esc_html_e( 'Max. URLs', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number"
						   id="kurs_booking_spam_max_urls"
						   name="kurs_booking_spam_max_urls"
						   value="<?php echo esc_attr( $max_urls ); ?>"
						   min="0"
						   max="10"
						   style="width: 80px;">
					<p class="description"><?php esc_html_e( 'Maximale Anzahl URLs in allen Textfeldern zusammen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_spam_keywords"><?php esc_html_e( 'Zusätzliche Sperr-Wörter', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<textarea id="kurs_booking_spam_keywords"
							  name="kurs_booking_spam_keywords"
							  rows="5"
							  class="large-text"
							  placeholder="<?php esc_attr_e( 'Ein Wort/Phrase pro Zeile', 'kurs-booking' ); ?>"><?php echo esc_textarea( $custom_keywords ); ?></textarea>
					<p class="description">
						<?php esc_html_e( 'Eigene Sperr-Wörter (eines pro Zeile). Vordefiniert sind bereits typische Spam-Begriffe (Viagra, Casino, Bitcoin, etc.).', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>
		</table>

		<!-- Info Box -->
		<div class="notice notice-warning inline" style="margin: 20px 0;">
			<p>
				<strong><?php esc_html_e( 'Hinweis:', 'kurs-booking' ); ?></strong>
				<?php esc_html_e( 'Spam-Versuche werden in den WordPress-Logs protokolliert. Bei Problemen prüfen Sie die Logs unter wp-content/debug.log.', 'kurs-booking' ); ?>
			</p>
		</div>
		<?php
	}

	/**
	 * Render portal tab (Kundenportal)
	 */
	private static function render_portal_tab(): void {
		$portal_secret      = get_option( 'kurs_booking_portal_secret', '' );
		$portal_url         = get_option( 'kurs_booking_portal_url', '' );
		$portal_webhook_url = get_option( 'kurs_booking_portal_webhook_url', '' );
		?>
		<h2><?php esc_html_e( 'Kundenportal-Integration', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Einstellungen für die Verbindung zum externen Kundenportal. Das Portal ermöglicht Kunden, ihre Buchungen, Rechnungen und Videos einzusehen.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_portal_url"><?php esc_html_e( 'Portal-URL', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="url"
						   id="kurs_booking_portal_url"
						   name="kurs_booking_portal_url"
						   value="<?php echo esc_attr( $portal_url ); ?>"
						   class="regular-text"
						   placeholder="https://portal.example.com">.
					<p class="description">
						<?php esc_html_e( 'Basis-URL des Kundenportals (z.B. https://portal.example.com). Wird für "Ich bin Kunde" im Buchungsformular benötigt.', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>
			<tr>
				<th scope="row">
					<label for="kurs_booking_portal_secret"><?php esc_html_e( 'API-Secret', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="password"
						   id="kurs_booking_portal_secret"
						   name="kurs_booking_portal_secret"
						   value="<?php echo esc_attr( $portal_secret ); ?>"
						   class="regular-text"
						   autocomplete="new-password">
					<button type="button" class="button" id="generate-portal-secret">
						<?php esc_html_e( 'Generieren', 'kurs-booking' ); ?>
					</button>
					<p class="description">
						<?php esc_html_e( 'Gemeinsames Secret zur Authentifizierung zwischen Portal und WordPress. Muss im Portal identisch konfiguriert sein.', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>
			<tr>
				<th scope="row">
					<label for="kurs_booking_portal_webhook_url"><?php esc_html_e( 'Portal-Webhook-URL', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="url"
						   id="kurs_booking_portal_webhook_url"
						   name="kurs_booking_portal_webhook_url"
						   value="<?php echo esc_attr( $portal_webhook_url ); ?>"
						   class="regular-text"
						   placeholder="https://portal.example.com/api/webhook/booking">.
					<p class="description">
						<?php esc_html_e( 'URL des Portal-Webhooks. Bei Buchungen wird automatisch ein Kunde im Portal angelegt.', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>
		</table>

		<hr style="margin: 30px 0;">

		<h3><?php esc_html_e( 'WordPress REST API', 'kurs-booking' ); ?></h3>
		<p class="description">
			<?php esc_html_e( 'Das Portal fragt Buchungen und Daten über diese Endpunkte ab:', 'kurs-booking' ); ?>
		</p>

		<table class="widefat" style="max-width: 700px; margin-top: 15px;">
			<thead>
				<tr>
					<th><?php esc_html_e( 'Endpunkt', 'kurs-booking' ); ?></th>
					<th><?php esc_html_e( 'Beschreibung', 'kurs-booking' ); ?></th>
				</tr>
			</thead>
			<tbody>
				<tr>
					<td><code>GET /wp-json/kurs-booking/v1/bookings?email=...</code></td>
					<td><?php esc_html_e( 'Buchungsliste eines Kunden', 'kurs-booking' ); ?></td>
				</tr>
				<tr>
					<td><code>GET /wp-json/kurs-booking/v1/bookings/{id}</code></td>
					<td><?php esc_html_e( 'Buchungsdetails', 'kurs-booking' ); ?></td>
				</tr>
				<tr>
					<td><code>POST /wp-json/kurs-booking/v1/bookings/{id}/cancel</code></td>
					<td><?php esc_html_e( 'Stornierung beantragen', 'kurs-booking' ); ?></td>
				</tr>
				<tr>
					<td><code>GET /wp-json/kurs-booking/v1/invoices?email=...</code></td>
					<td><?php esc_html_e( 'Rechnungen (via sevDesk)', 'kurs-booking' ); ?></td>
				</tr>
				<tr>
					<td><code>GET /wp-json/kurs-booking/v1/videos?email=...</code></td>
					<td><?php esc_html_e( 'Verfügbare Videos', 'kurs-booking' ); ?></td>
				</tr>
			</tbody>
		</table>

		<p class="description" style="margin-top: 15px;">
			<strong><?php esc_html_e( 'Authentifizierung:', 'kurs-booking' ); ?></strong>
			<?php esc_html_e( 'Alle Anfragen müssen den Header', 'kurs-booking' ); ?>
			<code>X-Portal-Secret: &lt;API-Secret&gt;</code>
			<?php esc_html_e( 'enthalten.', 'kurs-booking' ); ?>
		</p>

		<script>
		jQuery(document).ready(function($) {
			$('#generate-portal-secret').on('click', function() {
				var chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
				var secret = '';
				for (var i = 0; i < 32; i++) {
					secret += chars.charAt(Math.floor(Math.random() * chars.length));
				}
				$('#kurs_booking_portal_secret').attr('type', 'text').val(secret);
			});
		});
		</script>
		<?php
	}

	/**
	 * Render masterdata tab (Stammdaten)
	 */
	private static function render_masterdata_tab(): void {
		$instructors = get_option( 'kurs_booking_instructors', array() );
		$horses      = get_option( 'kurs_booking_horses', array() );
		$locations   = get_option( 'kurs_booking_locations', array() );

		if ( ! is_array( $instructors ) ) {
			$instructors = array();
		}
		if ( ! is_array( $horses ) ) {
			$horses = array();
		}
		if ( ! is_array( $locations ) ) {
			$locations = array();
		}
		?>
		<h2><?php esc_html_e( 'Reitlehrer/innen', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Liste der verfügbaren Reitlehrer/innen für die Kurs-Zuweisung.', 'kurs-booking' ); ?>
		</p>

		<div id="kurs-booking-instructors-container" class="kurs-booking-repeater-container">
			<?php foreach ( $instructors as $index => $instructor ) : ?>
				<div class="kurs-booking-repeater-row" data-index="<?php echo esc_attr( $index ); ?>">
					<input type="text"
						   name="kurs_booking_instructors[<?php echo esc_attr( $index ); ?>]"
						   value="<?php echo esc_attr( $instructor ); ?>"
						   placeholder="<?php esc_attr_e( 'Name des Reitlehrers/der Reitlehrerin', 'kurs-booking' ); ?>"
						   class="regular-text">
					<button type="button" class="button kurs-booking-remove-row">
						<span class="dashicons dashicons-trash"></span>
					</button>
				</div>
			<?php endforeach; ?>
		</div>
		<button type="button" class="button kurs-booking-add-instructor" data-container="kurs-booking-instructors-container">
			<span class="dashicons dashicons-plus-alt2"></span>
			<?php esc_html_e( 'Reitlehrer/in hinzufügen', 'kurs-booking' ); ?>
		</button>

		<hr style="margin: 30px 0;">

		<h2><?php esc_html_e( 'Pferde', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Liste der verfügbaren Pferde für die Kurs-Zuweisung. Im Kurs kann auch "Andere" gewählt und ein freier Text eingegeben werden.', 'kurs-booking' ); ?>
		</p>

		<div id="kurs-booking-horses-container" class="kurs-booking-repeater-container">
			<?php foreach ( $horses as $index => $horse ) : ?>
				<div class="kurs-booking-repeater-row" data-index="<?php echo esc_attr( $index ); ?>">
					<input type="text"
						   name="kurs_booking_horses[<?php echo esc_attr( $index ); ?>]"
						   value="<?php echo esc_attr( $horse ); ?>"
						   placeholder="<?php esc_attr_e( 'Name des Pferdes', 'kurs-booking' ); ?>"
						   class="regular-text">
					<button type="button" class="button kurs-booking-remove-row">
						<span class="dashicons dashicons-trash"></span>
					</button>
				</div>
			<?php endforeach; ?>
		</div>
		<button type="button" class="button kurs-booking-add-horse" data-container="kurs-booking-horses-container">
			<span class="dashicons dashicons-plus-alt2"></span>
			<?php esc_html_e( 'Pferd hinzufügen', 'kurs-booking' ); ?>
		</button>

		<hr style="margin: 30px 0;">

		<h2><?php esc_html_e( 'Veranstaltungsorte', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Liste der häufig verwendeten Veranstaltungsorte. Bei Auswahl wird die Webseite automatisch ausgefüllt. Im Kurs kann auch "Andere" gewählt werden.', 'kurs-booking' ); ?>
		</p>

		<div id="kurs-booking-locations-container" class="kurs-booking-repeater-container">
			<?php foreach ( $locations as $index => $location ) : ?>
				<div class="kurs-booking-repeater-row kurs-booking-location-row" data-index="<?php echo esc_attr( $index ); ?>">
					<input type="text"
						   name="kurs_booking_locations[<?php echo esc_attr( $index ); ?>][name]"
						   value="<?php echo esc_attr( $location['name'] ?? '' ); ?>"
						   placeholder="<?php esc_attr_e( 'Name / Adresse', 'kurs-booking' ); ?>"
						   class="regular-text">
					<input type="url"
						   name="kurs_booking_locations[<?php echo esc_attr( $index ); ?>][url]"
						   value="<?php echo esc_url( $location['url'] ?? '' ); ?>"
						   placeholder="<?php esc_attr_e( 'Webseite (optional)', 'kurs-booking' ); ?>"
						   class="regular-text">
					<button type="button" class="button kurs-booking-remove-row">
						<span class="dashicons dashicons-trash"></span>
					</button>
				</div>
			<?php endforeach; ?>
		</div>
		<button type="button" class="button kurs-booking-add-location" data-container="kurs-booking-locations-container">
			<span class="dashicons dashicons-plus-alt2"></span>
			<?php esc_html_e( 'Veranstaltungsort hinzufügen', 'kurs-booking' ); ?>
		</button>

		<script id="kurs-booking-instructor-template" type="text/template">
			<div class="kurs-booking-repeater-row" data-index="__INDEX__">
				<input type="text"
					   name="kurs_booking_instructors[__INDEX__]"
					   value=""
					   placeholder="<?php esc_attr_e( 'Name des Reitlehrers/der Reitlehrerin', 'kurs-booking' ); ?>"
					   class="regular-text">
				<button type="button" class="button kurs-booking-remove-row">
					<span class="dashicons dashicons-trash"></span>
				</button>
			</div>
		</script>

		<script id="kurs-booking-horse-template" type="text/template">
			<div class="kurs-booking-repeater-row" data-index="__INDEX__">
				<input type="text"
					   name="kurs_booking_horses[__INDEX__]"
					   value=""
					   placeholder="<?php esc_attr_e( 'Name des Pferdes', 'kurs-booking' ); ?>"
					   class="regular-text">
				<button type="button" class="button kurs-booking-remove-row">
					<span class="dashicons dashicons-trash"></span>
				</button>
			</div>
		</script>

		<script id="kurs-booking-location-template" type="text/template">
			<div class="kurs-booking-repeater-row kurs-booking-location-row" data-index="__INDEX__">
				<input type="text"
					   name="kurs_booking_locations[__INDEX__][name]"
					   value=""
					   placeholder="<?php esc_attr_e( 'Name / Adresse', 'kurs-booking' ); ?>"
					   class="regular-text">
				<input type="url"
					   name="kurs_booking_locations[__INDEX__][url]"
					   value=""
					   placeholder="<?php esc_attr_e( 'Webseite (optional)', 'kurs-booking' ); ?>"
					   class="regular-text">
				<button type="button" class="button kurs-booking-remove-row">
					<span class="dashicons dashicons-trash"></span>
				</button>
			</div>
		</script>
		<?php
	}

	/**
	 * Render booking tab
	 */
	private static function render_booking_tab(): void {
		?>
		<h2><?php esc_html_e( 'Buchungs-Einstellungen', 'kurs-booking' ); ?></h2>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_number_prefix"><?php esc_html_e( 'Buchungsnummer-Prefix', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_number_prefix" id="kurs_booking_number_prefix"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_number_prefix', 'BK' ) ); ?>"
						   class="small-text">
					<p class="description"><?php esc_html_e( 'Beispiel: BK-2025-0001', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_next_number"><?php esc_html_e( 'Nächste Buchungsnummer', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_next_number" id="kurs_booking_next_number"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_next_number', 1 ) ); ?>"
						   class="small-text" min="1">
					<p class="description"><?php esc_html_e( 'Auto-Increment Zähler für Buchungsnummern.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_confirm_validity_hours"><?php esc_html_e( 'Bestätigungslink gültig', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_confirm_validity_hours" id="kurs_booking_confirm_validity_hours"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_confirm_validity_hours', 48 ) ); ?>"
						   class="small-text" min="1" max="168">
					<span><?php esc_html_e( 'Stunden', 'kurs-booking' ); ?></span>
					<p class="description"><?php esc_html_e( 'Wie lange ist der Double-Opt-In Bestätigungslink gültig?', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_default_ticket_name"><?php esc_html_e( 'Standard-Ticket-Name', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_default_ticket_name" id="kurs_booking_default_ticket_name"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_default_ticket_name', 'Ticket' ) ); ?>"
						   class="regular-text">
					<p class="description"><?php esc_html_e( 'Fallback-Name wenn kein Ticket im Kurs definiert ist.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_admin_email"><?php esc_html_e( 'Admin-Email', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="email" name="kurs_booking_admin_email" id="kurs_booking_admin_email"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_admin_email', get_option( 'admin_email' ) ) ); ?>"
						   class="regular-text">
					<p class="description"><?php esc_html_e( 'Empfänger für neue Buchungs-Benachrichtigungen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'BCC an Admin', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_bcc_admin" value="1"
							   <?php checked( get_option( 'kurs_booking_bcc_admin', true ) ); ?>>
						<?php esc_html_e( 'Admin erhält Kopie aller Buchungs-Emails', 'kurs-booking' ); ?>
					</label>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Leere Felder anzeigen', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_show_empty_fields" value="1"
							   <?php checked( get_option( 'kurs_booking_show_empty_fields', false ) ); ?>>
						<?php esc_html_e( 'Alle Felder in der Buchungsansicht anzeigen (auch wenn leer)', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Wenn aktiviert, werden leere Felder mit "—" angezeigt statt ausgeblendet.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_max_tickets"><?php esc_html_e( 'Max. Tickets pro Buchung', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_max_tickets" id="kurs_booking_max_tickets"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_max_tickets', 10 ) ); ?>"
						   class="small-text" min="1" max="100">
					<p class="description"><?php esc_html_e( 'Maximale Anzahl Tickets die ein Kunde in einer Buchung kaufen kann.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render prices & VAT tab
	 */
	private static function render_prices_tab(): void {
		?>
		<h2><?php esc_html_e( 'Preise & Mehrwertsteuer', 'kurs-booking' ); ?></h2>

		<table class="form-table">
			<tr>
				<th scope="row"><?php esc_html_e( 'Preisanzeige', 'kurs-booking' ); ?></th>
				<td>
					<fieldset>
						<label>
							<input type="radio" name="kurs_booking_price_display" value="gross"
								   <?php checked( get_option( 'kurs_booking_price_display', 'gross' ), 'gross' ); ?>>
							<?php esc_html_e( 'Brutto (inkl. MwSt)', 'kurs-booking' ); ?>
						</label><br>
						<label>
							<input type="radio" name="kurs_booking_price_display" value="net"
								   <?php checked( get_option( 'kurs_booking_price_display', 'gross' ), 'net' ); ?>>
							<?php esc_html_e( 'Netto (zzgl. MwSt)', 'kurs-booking' ); ?>
						</label>
					</fieldset>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_vat_rate"><?php esc_html_e( 'MwSt-Satz', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_vat_rate" id="kurs_booking_vat_rate"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_vat_rate', 19 ) ); ?>"
						   class="small-text" min="0" max="100" step="0.01">
					<span>%</span>
					<p class="description"><?php esc_html_e( 'Standard: 19% (Deutschland)', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Kleinunternehmer', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_small_business" value="1"
							   <?php checked( get_option( 'kurs_booking_small_business', false ) ); ?>>
						<?php esc_html_e( 'Kleinunternehmer-Regelung nach §19 UStG anwenden', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Wenn aktiviert, wird keine MwSt ausgewiesen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_currency_symbol"><?php esc_html_e( 'Währungssymbol', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_currency_symbol" id="kurs_booking_currency_symbol"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_currency_symbol', '€' ) ); ?>"
						   class="small-text">
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Währungsposition', 'kurs-booking' ); ?></th>
				<td>
					<select name="kurs_booking_currency_position">
						<option value="before" <?php selected( get_option( 'kurs_booking_currency_position', 'after' ), 'before' ); ?>>
							<?php esc_html_e( 'Vor dem Betrag (€ 100)', 'kurs-booking' ); ?>
						</option>
						<option value="after" <?php selected( get_option( 'kurs_booking_currency_position', 'after' ), 'after' ); ?>>
							<?php esc_html_e( 'Nach dem Betrag (100 €)', 'kurs-booking' ); ?>
						</option>
					</select>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_decimal_separator"><?php esc_html_e( 'Dezimaltrennzeichen', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_decimal_separator" id="kurs_booking_decimal_separator"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_decimal_separator', ',' ) ); ?>"
						   class="small-text" maxlength="1">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_thousand_separator"><?php esc_html_e( 'Tausendertrennzeichen', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_thousand_separator" id="kurs_booking_thousand_separator"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_thousand_separator', '.' ) ); ?>"
						   class="small-text" maxlength="1">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_decimals"><?php esc_html_e( 'Dezimalstellen', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_decimals" id="kurs_booking_decimals"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_decimals', 2 ) ); ?>"
						   class="small-text" min="0" max="4">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_default_deposit_percent"><?php esc_html_e( 'Standard-Anzahlung', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_default_deposit_percent" id="kurs_booking_default_deposit_percent"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_default_deposit_percent', 0 ) ); ?>"
						   class="small-text" min="0" max="100">
					<span>%</span>
					<p class="description"><?php esc_html_e( 'Standard-Anzahlung in Prozent (0 = keine Anzahlung). Kann pro Kurs überschrieben werden.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_manual_payment_hint"><?php esc_html_e( 'Hinweis manuelle Verrechnung', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_manual_payment_hint" id="kurs_booking_manual_payment_hint"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_manual_payment_hint', 'Wird vor Ort verrechnet' ) ); ?>"
						   class="regular-text">
					<p class="description"><?php esc_html_e( 'Dieser Text wird angezeigt, wenn eine Preisvariante nicht automatisch über sevDesk verrechnet wird. Kann pro Variante überschrieben werden.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render cancellation tab
	 */
	private static function render_cancellation_tab(): void {
		?>
		<h2><?php esc_html_e( 'Stornobedingungen', 'kurs-booking' ); ?></h2>
		<p class="description"><?php esc_html_e( 'Diese Einstellungen werden für automatisch generierte Stornobedingungen verwendet.', 'kurs-booking' ); ?></p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_cancel_free_days"><?php esc_html_e( 'Kostenfrei stornieren bis', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_cancel_free_days" id="kurs_booking_cancel_free_days"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_cancel_free_days', 28 ) ); ?>"
						   class="small-text" min="0">
					<span><?php esc_html_e( 'Tage vor Kursbeginn', 'kurs-booking' ); ?></span>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_cancel_partial_days"><?php esc_html_e( 'Teilstorno bis', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_cancel_partial_days" id="kurs_booking_cancel_partial_days"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_cancel_partial_days', 14 ) ); ?>"
						   class="small-text" min="0">
					<span><?php esc_html_e( 'Tage vor Kursbeginn', 'kurs-booking' ); ?></span>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_cancel_partial_percent"><?php esc_html_e( 'Teilstorno-Gebühr', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_cancel_partial_percent" id="kurs_booking_cancel_partial_percent"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_cancel_partial_percent', 50 ) ); ?>"
						   class="small-text" min="0" max="100">
					<span>%</span>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_cancel_custom_text"><?php esc_html_e( 'Eigener Storno-Text', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<textarea name="kurs_booking_cancel_custom_text" id="kurs_booking_cancel_custom_text"
							  rows="5" class="large-text"><?php echo esc_textarea( get_option( 'kurs_booking_cancel_custom_text', '' ) ); ?></textarea>
					<p class="description"><?php esc_html_e( 'Wenn leer, wird aus obigen Werten automatisch generiert.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>

		<h3><?php esc_html_e( 'Erweiterte Storno-Optionen', 'kurs-booking' ); ?></h3>
		<table class="form-table">
			<tr>
				<th scope="row">
					<?php esc_html_e( 'Anzahlung bei Storno', 'kurs-booking' ); ?>
				</th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_cancel_deposit_retained" value="1"
							   <?php checked( get_option( 'kurs_booking_cancel_deposit_retained', '1' ), '1' ); ?>>
						<?php esc_html_e( 'Anzahlung wird bei Stornierung nicht erstattet', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Die Anzahlung (falls aktiviert) wird bei jeder Stornierung einbehalten.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<?php esc_html_e( 'Ersatzteilnehmer', 'kurs-booking' ); ?>
				</th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_cancel_allow_replacement" value="1"
							   <?php checked( get_option( 'kurs_booking_cancel_allow_replacement', '1' ), '1' ); ?>>
						<?php esc_html_e( 'Ersatzteilnehmer erlauben (keine Stornokosten)', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Wenn ein Ersatzteilnehmer gestellt wird, entfallen die Stornokosten.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>

		<h3><?php esc_html_e( 'Vorschau (automatisch generiert)', 'kurs-booking' ); ?></h3>
		<div class="notice notice-info inline" style="padding: 10px;">
			<pre style="margin: 0; white-space: pre-wrap;"><?php echo esc_html( self::get_cancellation_text_preview() ); ?></pre>
		</div>
		<?php
	}

	/**
	 * Render legal tab
	 */
	private static function render_legal_tab(): void {
		$pages = get_pages();
		?>
		<h2><?php esc_html_e( 'Rechtliche Einstellungen', 'kurs-booking' ); ?></h2>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_agb_page_id"><?php esc_html_e( 'AGB-Seite', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<select name="kurs_booking_agb_page_id" id="kurs_booking_agb_page_id">
						<option value="0"><?php esc_html_e( '— Seite auswählen —', 'kurs-booking' ); ?></option>
						<?php foreach ( $pages as $page ) : ?>
							<option value="<?php echo esc_attr( (string) $page->ID ); ?>"
									<?php selected( get_option( 'kurs_booking_agb_page_id', 0 ), $page->ID ); ?>>
								<?php echo esc_html( $page->post_title ); ?>
							</option>
						<?php endforeach; ?>
					</select>
					<p class="description"><?php esc_html_e( 'Verlinkt im Buchungsformular.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_privacy_page_id"><?php esc_html_e( 'Datenschutz-Seite', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<select name="kurs_booking_privacy_page_id" id="kurs_booking_privacy_page_id">
						<option value="0"><?php esc_html_e( '— Seite auswählen —', 'kurs-booking' ); ?></option>
						<?php foreach ( $pages as $page ) : ?>
							<option value="<?php echo esc_attr( (string) $page->ID ); ?>"
									<?php selected( get_option( 'kurs_booking_privacy_page_id', 0 ), $page->ID ); ?>>
								<?php echo esc_html( $page->post_title ); ?>
							</option>
						<?php endforeach; ?>
					</select>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_withdrawal_notice"><?php esc_html_e( 'Widerrufsbelehrung', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<textarea name="kurs_booking_withdrawal_notice" id="kurs_booking_withdrawal_notice"
							  rows="4" class="large-text"><?php echo esc_textarea( get_option( 'kurs_booking_withdrawal_notice', self::get_default_withdrawal_notice() ) ); ?></textarea>
					<p class="description"><?php esc_html_e( 'Hinweis zum Widerrufsrecht bei Freizeitdienstleistungen.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_agb_checkbox_text"><?php esc_html_e( 'AGB-Checkbox Text', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<textarea name="kurs_booking_agb_checkbox_text" id="kurs_booking_agb_checkbox_text"
							  rows="3" class="large-text"><?php echo esc_textarea( get_option( 'kurs_booking_agb_checkbox_text', self::get_default_agb_checkbox_text() ) ); ?></textarea>
					<p class="description"><?php esc_html_e( 'Text für die AGB-Checkbox im Buchungsformular. Verwenden Sie [AGB] und [Datenschutz] als Platzhalter für Links.', 'kurs-booking' ); ?></p>
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render bank tab
	 */
	private static function render_bank_tab(): void {
		?>
		<h2><?php esc_html_e( 'Bankverbindung', 'kurs-booking' ); ?></h2>
		<p class="description"><?php esc_html_e( 'Wird in Bestätigungs-Emails und Rechnungen angezeigt.', 'kurs-booking' ); ?></p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_bank_account_holder"><?php esc_html_e( 'Kontoinhaber', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_bank_account_holder" id="kurs_booking_bank_account_holder"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_bank_account_holder', get_option( 'kurs_booking_company_name', '' ) ) ); ?>"
						   class="regular-text">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_bank_iban"><?php esc_html_e( 'IBAN', 'kurs-booking' ); ?> *</label>
				</th>
				<td>
					<input type="text" name="kurs_booking_bank_iban" id="kurs_booking_bank_iban"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_bank_iban', '' ) ); ?>"
						   class="regular-text" placeholder="DE00 0000 0000 0000 0000 00">
					<p class="description"><?php esc_html_e( 'Pflichtfeld bei Zahlung per Rechnung.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_bank_bic"><?php esc_html_e( 'BIC/SWIFT', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_bank_bic" id="kurs_booking_bank_bic"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_bank_bic', '' ) ); ?>"
						   class="regular-text" placeholder="ABCDEFGH">
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_bank_name"><?php esc_html_e( 'Bank', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_bank_name" id="kurs_booking_bank_name"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_bank_name', '' ) ); ?>"
						   class="regular-text" placeholder="<?php esc_attr_e( 'Name der Bank', 'kurs-booking' ); ?>">
				</td>
			</tr>
		</table>
		<?php
	}

	/**
	 * Render sevDesk tab
	 */
	private static function render_sevdesk_tab(): void {
		?>
		<h2><?php esc_html_e( 'sevDesk Integration', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Verbinden Sie das Plugin mit Ihrem sevDesk-Konto für automatische Rechnungserstellung.', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_sevdesk_api_token"><?php esc_html_e( 'API-Token', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="password" name="kurs_booking_sevdesk_api_token" id="kurs_booking_sevdesk_api_token"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_sevdesk_api_token', '' ) ); ?>"
						   class="regular-text">
					<p class="description">
						<?php
						printf(
							/* translators: %s: sevDesk API URL */
							esc_html__( 'API-Token aus sevDesk: Einstellungen > Benutzer > API-Token. %s', 'kurs-booking' ),
							'<a href="https://my.sevdesk.de/#/admin/userManagement" target="_blank">' . esc_html__( 'Zu sevDesk', 'kurs-booking' ) . '</a>'
						);
						?>
					</p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_sevdesk_user_id"><?php esc_html_e( 'User ID', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_sevdesk_user_id" id="kurs_booking_sevdesk_user_id"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_sevdesk_user_id', '' ) ); ?>"
						   class="small-text" min="0">
					<p class="description"><?php esc_html_e( 'sevDesk User ID für "Erstellt von" Feld.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_sevdesk_contact_category"><?php esc_html_e( 'Kontakt-Kategorie', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="number" name="kurs_booking_sevdesk_contact_category" id="kurs_booking_sevdesk_contact_category"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_sevdesk_contact_category', '' ) ); ?>"
						   class="small-text" min="0">
					<p class="description"><?php esc_html_e( 'Standard-Kategorie-ID für neue Kontakte in sevDesk.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Automatische Rechnung', 'kurs-booking' ); ?></th>
				<td>
					<label>
						<input type="checkbox" name="kurs_booking_sevdesk_auto_invoice" value="1"
							   <?php checked( get_option( 'kurs_booking_sevdesk_auto_invoice', true ) ); ?>>
						<?php esc_html_e( 'Rechnung automatisch bei bestätigter Buchung erstellen', 'kurs-booking' ); ?>
					</label>
					<br><br>
					<label>
						<input type="checkbox" name="kurs_booking_sevdesk_auto_send_invoice" value="1"
							   <?php checked( get_option( 'kurs_booking_sevdesk_auto_send_invoice', false ) ); ?>>
						<?php esc_html_e( 'Rechnung automatisch per E-Mail an Kunden senden', 'kurs-booking' ); ?>
					</label>
					<p class="description"><?php esc_html_e( 'Sendet die Rechnung über sevDesk an den Kunden.', 'kurs-booking' ); ?></p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_sevdesk_invoice_status"><?php esc_html_e( 'Rechnungs-Status', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<select name="kurs_booking_sevdesk_invoice_status" id="kurs_booking_sevdesk_invoice_status">
						<option value="100" <?php selected( get_option( 'kurs_booking_sevdesk_invoice_status', 100 ), 100 ); ?>>
							<?php esc_html_e( 'Entwurf (zum Prüfen)', 'kurs-booking' ); ?>
						</option>
						<option value="200" <?php selected( get_option( 'kurs_booking_sevdesk_invoice_status', 100 ), 200 ); ?>>
							<?php esc_html_e( 'Offen (sofort versendet)', 'kurs-booking' ); ?>
						</option>
					</select>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_sevdesk_position_text"><?php esc_html_e( 'Rechnungsposition Text', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="text" name="kurs_booking_sevdesk_position_text" id="kurs_booking_sevdesk_position_text"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_sevdesk_position_text', '{kurs_name} (Buchung: {buchungs_nummer})' ) ); ?>"
						   class="large-text">
					<p class="description">
						<?php esc_html_e( 'Platzhalter:', 'kurs-booking' ); ?>
						<code>{kurs_name}</code>,
						<code>{buchungs_nummer}</code>,
						<code>{datum}</code>,
						<code>{tickets}</code>
					</p>
					<p class="description">
						<?php esc_html_e( 'Beispiel:', 'kurs-booking' ); ?>
						<em>"Hundetraining Basis-Kurs (Buchung: WW-2025-0001)"</em>
					</p>
				</td>
			</tr>
		</table>

		<?php if ( get_option( 'kurs_booking_sevdesk_api_token' ) ) : ?>
			<h3><?php esc_html_e( 'Verbindungstest', 'kurs-booking' ); ?></h3>
			<p>
				<button type="button" class="button" id="kurs-booking-test-sevdesk">
					<?php esc_html_e( 'Verbindung testen', 'kurs-booking' ); ?>
				</button>
				<span id="kurs-booking-sevdesk-result"></span>
			</p>
		<?php endif; ?>
		<?php
	}

	/**
	 * Render video service settings tab
	 */
	private static function render_video_tab(): void {
		?>
		<h2><?php esc_html_e( 'Video-Service', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Konfiguration fuer den Video-Streaming-Service (HLS Video-Hosting fuer Kurs-Aufzeichnungen).', 'kurs-booking' ); ?>
		</p>

		<table class="form-table">
			<tr>
				<th scope="row">
					<label for="kurs_booking_video_api_url"><?php esc_html_e( 'Video-Service URL', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="url" name="kurs_booking_video_api_url" id="kurs_booking_video_api_url"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_video_api_url', '' ) ); ?>"
						   class="regular-text"
						   placeholder="https://videos.islandpferde-melanieworbs.de">.
					<p class="description">
						<?php esc_html_e( 'Basis-URL des Video-Service (ohne /api/v1/).', 'kurs-booking' ); ?>
						<br>
						<?php esc_html_e( 'Docker: http://kurs_video_api:8000 | Extern: http://192.168.100.93:8501', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>

			<tr>
				<th scope="row">
					<label for="kurs_booking_video_api_key"><?php esc_html_e( 'API-Key', 'kurs-booking' ); ?></label>
				</th>
				<td>
					<input type="password" name="kurs_booking_video_api_key" id="kurs_booking_video_api_key"
						   value="<?php echo esc_attr( get_option( 'kurs_booking_video_api_key', '' ) ); ?>"
						   class="regular-text">
					<p class="description">
						<?php esc_html_e( 'API-Key fuer die Authentifizierung mit dem Video-Service.', 'kurs-booking' ); ?>
					</p>
				</td>
			</tr>

			<tr>
				<th scope="row"><?php esc_html_e( 'Status', 'kurs-booking' ); ?></th>
				<td>
					<?php
					$api_url = get_option( 'kurs_booking_video_api_url', '' );
					$api_key = get_option( 'kurs_booking_video_api_key', '' );

					if ( empty( $api_url ) || empty( $api_key ) ) {
						echo '<span class="dashicons dashicons-warning" style="color: #d63638;"></span> ';
						esc_html_e( 'Nicht konfiguriert - API-URL und API-Key erforderlich.', 'kurs-booking' );
					} else {
						echo '<span class="dashicons dashicons-yes-alt" style="color: #00a32a;"></span> ';
						esc_html_e( 'Konfiguriert', 'kurs-booking' );
					}
					?>
				</td>
			</tr>
		</table>

		<?php if ( ! empty( $api_url ) && ! empty( $api_key ) ) : ?>
			<h3><?php esc_html_e( 'Verbindungstest', 'kurs-booking' ); ?></h3>
			<p>
				<button type="button" class="button" id="kurs-booking-test-video-service">
					<?php esc_html_e( 'Video-Service testen', 'kurs-booking' ); ?>
				</button>
				<span id="kurs-booking-video-result" style="margin-left: 10px;"></span>
			</p>

			<script>
			jQuery(document).ready(function($) {
				$('#kurs-booking-test-video-service').on('click', function() {
					var $btn = $(this);
					var $result = $('#kurs-booking-video-result');

					$btn.prop('disabled', true);
					$result.html('<span class="spinner is-active" style="float: none;"></span> <?php echo esc_js( __( 'Teste Verbindung...', 'kurs-booking' ) ); ?>');

					$.ajax({
						url: ajaxurl,
						type: 'POST',
						data: {
							action: 'kurs_booking_test_video_service',
							nonce: '<?php echo esc_js( wp_create_nonce( 'kurs_booking_video_test' ) ); ?>'
						},
						success: function(response) {
							if (response.success) {
								$result.html('<span class="dashicons dashicons-yes-alt" style="color: #00a32a;"></span> ' + response.data.message);
							} else {
								$result.html('<span class="dashicons dashicons-warning" style="color: #d63638;"></span> ' + response.data.message);
							}
						},
						error: function() {
							$result.html('<span class="dashicons dashicons-warning" style="color: #d63638;"></span> <?php echo esc_js( __( 'Verbindungsfehler', 'kurs-booking' ) ); ?>');
						},
						complete: function() {
							$btn.prop('disabled', false);
						}
					});
				});
			});
			</script>
		<?php endif; ?>

		<hr>

		<h3><?php esc_html_e( 'Webhook-URL', 'kurs-booking' ); ?></h3>
		<p class="description">
			<?php esc_html_e( 'Diese URL muss im Video-Service als Webhook konfiguriert werden:', 'kurs-booking' ); ?>
		</p>
		<code style="display: block; padding: 10px; background: #f0f0f0; margin: 10px 0;">
			<?php echo esc_url( rest_url( 'kurs-booking/v1/video-webhook' ) ); ?>
		</code>

		<hr>

		<h3><?php esc_html_e( 'Hinweise', 'kurs-booking' ); ?></h3>
		<ul style="list-style: disc; margin-left: 20px;">
			<li><?php esc_html_e( 'Der Video-Service muss separat installiert und gestartet werden (Docker-Container).', 'kurs-booking' ); ?></li>
			<li><?php esc_html_e( 'Unterstuetzte Formate: MP4, MOV, AVI, MKV', 'kurs-booking' ); ?></li>
			<li><?php esc_html_e( 'Videos werden automatisch in HLS konvertiert (360p, 720p, 1080p).', 'kurs-booking' ); ?></li>
			<li><?php esc_html_e( 'Streaming erfordert JWT-Token (automatisch generiert fuer bezahlte Buchungen).', 'kurs-booking' ); ?></li>
		</ul>
		<?php
	}

	/**
	 * Save settings for current tab
	 *
	 * @param string $tab Current tab.
	 */
	private static function save_settings( string $tab ): void {
        // phpcs:disable WordPress.Security.NonceVerification.Missing -- Nonce verified in render_settings_page()
		switch ( $tab ) {
			case 'general':
				$general_fields = array(
					'kurs_booking_company_name'    => 'sanitize_text_field',
					'kurs_booking_company_street'  => 'sanitize_text_field',
					'kurs_booking_company_city'    => 'sanitize_text_field',
					'kurs_booking_company_phone'   => 'sanitize_text_field',
					'kurs_booking_company_email'   => 'sanitize_email',
					'kurs_booking_company_website' => 'esc_url_raw',
					'kurs_booking_company_ceo'     => 'sanitize_text_field',
					'kurs_booking_tax_number'      => 'sanitize_text_field',
					'kurs_booking_vat_id'          => 'sanitize_text_field',
					'kurs_booking_logo'            => 'absint',
				);

				foreach ( $general_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback below.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'modules':
				$modules = array();
				$module_keys = array(
					'videos',
					'sevdesk',
					'stornierung',
					'kurs_vorlagen',
					'stammdaten',
					'preisvarianten',
					'varianten_zusatz',
					'bedingte_felder',
					'widerrufsrecht',
				);

				foreach ( $module_keys as $key ) {
					$modules[ $key ] = ! empty( $_POST['kurs_booking_modules'][ $key ] );
				}

				update_option( 'kurs_booking_modules', $modules );
				break;

			case 'masterdata':
				// Save instructors.
				if ( isset( $_POST['kurs_booking_instructors'] ) && is_array( $_POST['kurs_booking_instructors'] ) ) {
					$instructors = array_values( array_filter( array_map( 'sanitize_text_field', wp_unslash( $_POST['kurs_booking_instructors'] ) ) ) );
					update_option( 'kurs_booking_instructors', $instructors );
				} else {
					update_option( 'kurs_booking_instructors', array() );
				}

				// Save horses.
				if ( isset( $_POST['kurs_booking_horses'] ) && is_array( $_POST['kurs_booking_horses'] ) ) {
					$horses = array_values( array_filter( array_map( 'sanitize_text_field', wp_unslash( $_POST['kurs_booking_horses'] ) ) ) );
					update_option( 'kurs_booking_horses', $horses );
				} else {
					update_option( 'kurs_booking_horses', array() );
				}

				// Save locations (with name and url).
				if ( isset( $_POST['kurs_booking_locations'] ) && is_array( $_POST['kurs_booking_locations'] ) ) {
					$locations = array();
					// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in loop below via sanitize_text_field() and esc_url_raw().
					foreach ( wp_unslash( $_POST['kurs_booking_locations'] ) as $loc ) {
						$name = sanitize_text_field( $loc['name'] ?? '' );
						if ( ! empty( $name ) ) {
							$locations[] = array(
								'name' => $name,
								'url'  => esc_url_raw( $loc['url'] ?? '' ),
							);
						}
					}
					update_option( 'kurs_booking_locations', array_values( $locations ) );
				} else {
					update_option( 'kurs_booking_locations', array() );
				}
				break;

			case 'fields':
				if ( isset( $_POST['kurs_booking_fields'] ) && is_array( $_POST['kurs_booking_fields'] ) ) {
					$fields = array();
					// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in loop below via sanitize_text_field(), sanitize_key(), etc.
					foreach ( wp_unslash( $_POST['kurs_booking_fields'] ) as $index => $field_data ) {
						$options = array();
						if ( ! empty( $field_data['options'] ) ) {
							// Options are comma-separated in the form.
							$options = array_filter(
								array_map( 'trim', explode( ',', sanitize_text_field( $field_data['options'] ) ) )
							);
						}

						// Generate name from label (slugified, unique).
						$label = sanitize_text_field( $field_data['label'] ?? '' );
						$name  = self::generate_field_name( $label, $fields );

						// Sprint 8.2: Produktarten array sanitization.
						$produktarten = array();
						if ( ! empty( $field_data['produktarten'] ) && is_array( $field_data['produktarten'] ) ) {
							$produktarten = array_map( 'sanitize_key', $field_data['produktarten'] );
							$produktarten = array_filter( $produktarten ); // Remove empty values.
						}

						$fields[] = array(
							'type'         => sanitize_key( $field_data['type'] ?? 'text' ),
							'name'         => $name,
							'label'        => $label,
							'placeholder'  => sanitize_text_field( $field_data['placeholder'] ?? '' ),
							'mandatory'    => ! empty( $field_data['mandatory'] ),
							'options'      => $options,
							'page'         => absint( $field_data['page'] ?? 0 ),
							'condition'    => sanitize_text_field( $field_data['condition'] ?? '' ),
							'active'       => ! empty( $field_data['active'] ),
							'half_width'   => ( ! empty( $field_data['half_width'] ) && '0' !== $field_data['half_width'] ),
							'width'        => absint( $field_data['width'] ?? 0 ),
							'basis_field'  => ( ! empty( $field_data['basis_field'] ) && '0' !== $field_data['basis_field'] ),
							'produktarten' => $produktarten,
						);
					}
					$json = wp_json_encode( $fields, JSON_UNESCAPED_UNICODE );
					// Use direct DB update to avoid WordPress caching issues.
					global $wpdb;
					$result = $wpdb->update(
						$wpdb->options,
						array( 'option_value' => $json ),
						array( 'option_name' => 'kurs_booking_custom_fields' )
					);
					// Clear caches after update.
					wp_cache_delete( 'kurs_booking_custom_fields', 'options' );
					wp_cache_delete( 'alloptions', 'options' );
				} else {
					update_option( 'kurs_booking_custom_fields', '[]' );
				}
				break;

			case 'emails':
				$email_fields = array(
					'kurs_booking_email_from_name'    => 'sanitize_text_field',
					'kurs_booking_email_from_address' => 'sanitize_email',
					'kurs_booking_email_bcc'          => 'sanitize_email',
					'kurs_booking_payment_due_days'   => 'absint',
					'kurs_booking_default_notes'      => 'sanitize_textarea_field',
				);

				foreach ( $email_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'booking':
				$booking_fields = array(
					'kurs_booking_number_prefix'           => 'sanitize_text_field',
					'kurs_booking_next_number'             => 'absint',
					'kurs_booking_confirm_validity_hours'  => 'absint',
					'kurs_booking_default_ticket_name'     => 'sanitize_text_field',
					'kurs_booking_admin_email'             => 'sanitize_email',
					'kurs_booking_max_tickets'             => 'absint',
				);

				foreach ( $booking_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				// Checkbox.
				update_option( 'kurs_booking_bcc_admin', isset( $_POST['kurs_booking_bcc_admin'] ) ? 1 : 0 );
				break;

			case 'prices':
				$price_fields = array(
					'kurs_booking_price_display'           => 'sanitize_key',
					'kurs_booking_vat_rate'                => 'floatval',
					'kurs_booking_currency_symbol'         => 'sanitize_text_field',
					'kurs_booking_currency_position'       => 'sanitize_key',
					'kurs_booking_decimal_separator'       => 'sanitize_text_field',
					'kurs_booking_thousand_separator'      => 'sanitize_text_field',
					'kurs_booking_decimals'                => 'absint',
					'kurs_booking_default_deposit_percent' => 'absint',
				);

				foreach ( $price_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				// Checkbox.
				update_option( 'kurs_booking_small_business', isset( $_POST['kurs_booking_small_business'] ) ? 1 : 0 );
				break;

			case 'cancellation':
				$cancel_fields = array(
					'kurs_booking_cancel_free_days'       => 'absint',
					'kurs_booking_cancel_partial_days'    => 'absint',
					'kurs_booking_cancel_partial_percent' => 'absint',
					'kurs_booking_cancel_custom_text'     => 'sanitize_textarea_field',
				);

				foreach ( $cancel_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'legal':
				$legal_fields = array(
					'kurs_booking_agb_page_id'        => 'absint',
					'kurs_booking_privacy_page_id'    => 'absint',
					'kurs_booking_withdrawal_notice'  => 'sanitize_textarea_field',
					'kurs_booking_agb_checkbox_text'  => 'wp_kses_post',
				);

				foreach ( $legal_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'bank':
				$bank_fields = array(
					'kurs_booking_bank_account_holder' => 'sanitize_text_field',
					'kurs_booking_bank_iban'           => 'sanitize_text_field',
					'kurs_booking_bank_bic'            => 'sanitize_text_field',
					'kurs_booking_bank_name'           => 'sanitize_text_field',
				);

				foreach ( $bank_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'payments':
				// Checkboxes.
				update_option( 'kurs_booking_gateway_invoice', isset( $_POST['kurs_booking_gateway_invoice'] ) ? 1 : 0 );
				update_option( 'kurs_booking_gateway_paypal', isset( $_POST['kurs_booking_gateway_paypal'] ) ? 1 : 0 );
				update_option( 'kurs_booking_gateway_stripe', isset( $_POST['kurs_booking_gateway_stripe'] ) ? 1 : 0 );
				break;

			case 'sevdesk':
				$sevdesk_fields = array(
					'kurs_booking_sevdesk_api_token'        => 'sanitize_text_field',
					'kurs_booking_sevdesk_user_id'          => 'absint',
					'kurs_booking_sevdesk_contact_category' => 'absint',
					'kurs_booking_sevdesk_invoice_status'   => 'absint',
					'kurs_booking_sevdesk_position_text'    => 'sanitize_text_field',
				);

				foreach ( $sevdesk_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				// Checkboxes.
				update_option( 'kurs_booking_sevdesk_auto_invoice', isset( $_POST['kurs_booking_sevdesk_auto_invoice'] ) ? 1 : 0 );
				update_option( 'kurs_booking_sevdesk_auto_send_invoice', isset( $_POST['kurs_booking_sevdesk_auto_send_invoice'] ) ? 1 : 0 );
				break;

			case 'video':
				$video_fields = array(
					'kurs_booking_video_api_url' => 'esc_url_raw',
					'kurs_booking_video_api_key' => 'sanitize_text_field',
				);

				foreach ( $video_fields as $field => $sanitizer ) {
					if ( isset( $_POST[ $field ] ) ) {
						// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized via $sanitizer() callback.
						$value = wp_unslash( $_POST[ $field ] );
						update_option( $field, $sanitizer( $value ) );
					}
				}
				break;

			case 'email_templates':
				$template_types = self::get_email_template_types();

				foreach ( $template_types as $type => $config ) {
					$subject_key = 'kurs_booking_email_tpl_' . $type . '_subject';
					$body_key    = 'kurs_booking_email_tpl_' . $type . '_body';

					// Save subject.
					if ( isset( $_POST[ $subject_key ] ) ) {
						$subject = sanitize_text_field( wp_unslash( $_POST[ $subject_key ] ) );
						update_option( $subject_key, $subject );
					}

					// Save body (allow HTML with wp_kses_post).
					if ( isset( $_POST[ $body_key ] ) ) {
						$body = wp_kses_post( wp_unslash( $_POST[ $body_key ] ) );
						update_option( $body_key, $body );
					}
				}
				break;

			case 'spam':
				// Layer 1: Cloudflare Turnstile.
				update_option( 'kurs_booking_turnstile_enabled', isset( $_POST['kurs_booking_turnstile_enabled'] ) ? 1 : 0 );
				update_option( 'kurs_booking_turnstile_test_mode', isset( $_POST['kurs_booking_turnstile_test_mode'] ) ? 1 : 0 );
				if ( isset( $_POST['kurs_booking_turnstile_site_key'] ) ) {
					update_option( 'kurs_booking_turnstile_site_key', sanitize_text_field( wp_unslash( $_POST['kurs_booking_turnstile_site_key'] ) ) );
				}
				if ( isset( $_POST['kurs_booking_turnstile_secret_key'] ) ) {
					update_option( 'kurs_booking_turnstile_secret_key', sanitize_text_field( wp_unslash( $_POST['kurs_booking_turnstile_secret_key'] ) ) );
				}
				if ( isset( $_POST['kurs_booking_turnstile_theme'] ) ) {
					update_option( 'kurs_booking_turnstile_theme', sanitize_key( wp_unslash( $_POST['kurs_booking_turnstile_theme'] ) ) );
				}

				// Layer 2: Honeypot + Time-based.
				update_option( 'kurs_booking_spam_honeypot', isset( $_POST['kurs_booking_spam_honeypot'] ) ? 1 : 0 );
				if ( isset( $_POST['kurs_booking_spam_min_time'] ) ) {
					update_option( 'kurs_booking_spam_min_time', absint( $_POST['kurs_booking_spam_min_time'] ) );
				}

				// Layer 3: Content filter.
				update_option( 'kurs_booking_spam_content_filter', isset( $_POST['kurs_booking_spam_content_filter'] ) ? 1 : 0 );
				if ( isset( $_POST['kurs_booking_spam_max_urls'] ) ) {
					update_option( 'kurs_booking_spam_max_urls', absint( $_POST['kurs_booking_spam_max_urls'] ) );
				}
				if ( isset( $_POST['kurs_booking_spam_keywords'] ) ) {
					update_option( 'kurs_booking_spam_keywords', sanitize_textarea_field( wp_unslash( $_POST['kurs_booking_spam_keywords'] ) ) );
				}
				break;

			case 'portal':
				// Portal URL.
				if ( isset( $_POST['kurs_booking_portal_url'] ) ) {
					update_option( 'kurs_booking_portal_url', esc_url_raw( wp_unslash( $_POST['kurs_booking_portal_url'] ) ) );
				}
				// Portal secret.
				if ( isset( $_POST['kurs_booking_portal_secret'] ) ) {
					update_option( 'kurs_booking_portal_secret', sanitize_text_field( wp_unslash( $_POST['kurs_booking_portal_secret'] ) ) );
				}
				// Portal webhook URL.
				if ( isset( $_POST['kurs_booking_portal_webhook_url'] ) ) {
					update_option( 'kurs_booking_portal_webhook_url', esc_url_raw( wp_unslash( $_POST['kurs_booking_portal_webhook_url'] ) ) );
				}
				break;

			case 'dienstleistungen':
				// Sprint 8.2: Save service types (Produktarten).
				if ( isset( $_POST['kurs_booking_dienstleistungen'] ) && is_array( $_POST['kurs_booking_dienstleistungen'] ) ) {
					$services = array();
					// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- Sanitized in loop below.
					foreach ( wp_unslash( $_POST['kurs_booking_dienstleistungen'] ) as $index => $data ) {
						$id = sanitize_key( $data['id'] ?? '' );

						// Generate ID from name if empty.
						if ( empty( $id ) ) {
							$name = sanitize_text_field( $data['name'] ?? '' );
							$id   = sanitize_title( $name );
							if ( empty( $id ) ) {
								continue; // Skip entries without name.
							}
							// Ensure unique ID.
							$original_id = $id;
							$counter     = 1;
							while ( isset( $services[ $id ] ) ) {
								$id = $original_id . '-' . $counter;
								++$counter;
							}
						}

						$services[ $id ] = array(
							'id'          => $id,
							'name'        => sanitize_text_field( $data['name'] ?? '' ),
							'label'       => sanitize_text_field( $data['label'] ?? '' ),
							'buchungsart' => in_array( ( $data['buchungsart'] ?? '' ), array( 'direkt', 'anfrage' ), true )
								? $data['buchungsart']
								: 'direkt',
							'terminart'   => in_array( ( $data['terminart'] ?? '' ), array( 'fix', 'individuell', 'unbegrenzt' ), true )
								? $data['terminart']
								: 'fix',
							'badge_color' => sanitize_hex_color( $data['badge_color'] ?? '#4CAF50' ) ?: '#4CAF50',
							'badge_icon'  => sanitize_key( $data['badge_icon'] ?? 'calendar-alt' ),
							'order'       => absint( $data['order'] ?? $index ),
							'active'      => ! empty( $data['active'] ),
							'system'      => ! empty( $data['system'] ),
						);
					}
					Kurs_Booking_Dienstleistungen::save( $services );
				}
				break;
		}
        // phpcs:enable
	}

	/**
	 * Get company data for email footer.
	 *
	 * @return array<string, string|int> Company data array.
	 */
	public static function get_company_data(): array {
		return array(
			'name'    => get_option( 'kurs_booking_company_name', '' ),
			'street'  => get_option( 'kurs_booking_company_street', '' ),
			'city'    => get_option( 'kurs_booking_company_city', '' ),
			'phone'   => get_option( 'kurs_booking_company_phone', '' ),
			'email'   => get_option( 'kurs_booking_company_email', '' ),
			'website' => get_option( 'kurs_booking_company_website', '' ),
			'ceo'     => get_option( 'kurs_booking_company_ceo', '' ),
			'tax'     => get_option( 'kurs_booking_tax_number', '' ),
			'vat'     => get_option( 'kurs_booking_vat_id', '' ),
			'logo'    => (int) get_option( 'kurs_booking_logo', 0 ),
		);
	}

	/**
	 * Core field names that get special handling (autocomplete, direct form name).
	 *
	 * @var array<string, array<string, string>>
	 */
	private static array $core_fields = array(
		'name'  => array(
			'autocomplete' => 'name',
			'type'         => 'text',
		),
		'email' => array(
			'autocomplete' => 'email',
			'type'         => 'email',
		),
		'phone' => array(
			'autocomplete' => 'tel',
			'type'         => 'tel',
		),
	);

	/**
	 * Check if a module is active.
	 *
	 * @param string $module_key The module key to check.
	 * @return bool True if module is active, false otherwise.
	 */
	public static function is_module_active( string $module_key ): bool {
		$modules = get_option( 'kurs_booking_modules', array() );

		// Default all modules to active if not explicitly set.
		$defaults = array(
			'videos'           => true,
			'sevdesk'          => true,
			'stornierung'      => true,
			'kurs_vorlagen'    => true,
			'stammdaten'       => true,
			'preisvarianten'   => true,
			'varianten_zusatz' => true,
			'bedingte_felder'  => true,
			'widerrufsrecht'   => true,
		);

		$modules = wp_parse_args( $modules, $defaults );

		return ! empty( $modules[ $module_key ] );
	}

	/**
	 * Get custom booking fields
	 *
	 * Normalizes field data from storage format to template format.
	 * Adds default core fields (Name, Email, Phone) if not present.
	 *
	 * @return array<int, array<string, mixed>> Array of custom fields.
	 */
	public static function get_custom_fields(): array {
		$data = get_option( 'kurs_booking_custom_fields', '[]' );

		// Handle both array (from update_option) and JSON string formats.
		if ( is_array( $data ) ) {
			$fields = $data;
		} else {
			$fields = json_decode( $data, true ) ?: array();
		}

		// Check which core fields exist.
		$has_core = array(
			'name'  => false,
			'email' => false,
			'phone' => false,
		);

		foreach ( $fields as $field ) {
			$field_name  = $field['name'] ?? '';
			$field_label = strtolower( $field['label'] ?? '' );
			$field_type  = $field['type'] ?? '';

			// Check by name, label, or type.
			if ( 'name' === $field_name || 'name' === $field_label ) {
				$has_core['name'] = true;
			} elseif ( 'email' === $field_name || 'e-mail' === $field_label || 'email' === $field_type ) {
				$has_core['email'] = true;
			} elseif ( 'phone' === $field_name || 'telefon' === $field_label || 'tel' === $field_type ) {
				$has_core['phone'] = true;
			}
		}

		// Add missing core fields at the beginning.
		$default_core_fields = array();
		if ( ! $has_core['name'] ) {
			$default_core_fields[] = array(
				'name'      => 'name',
				'label'     => __( 'Name', 'kurs-booking' ),
				'type'      => 'text',
				'mandatory' => true,
			);
		}
		if ( ! $has_core['email'] ) {
			$default_core_fields[] = array(
				'name'      => 'email',
				'label'     => __( 'E-Mail', 'kurs-booking' ),
				'type'      => 'email',
				'mandatory' => true,
			);
		}
		if ( ! $has_core['phone'] ) {
			$default_core_fields[] = array(
				'name'      => 'phone',
				'label'     => __( 'Telefon', 'kurs-booking' ),
				'type'      => 'tel',
				'mandatory' => false,
			);
		}

		// Merge: default core fields first, then user fields.
		$fields = array_merge( $default_core_fields, $fields );

		// Normalize fields to expected template format.
		$normalized = array();
		foreach ( $fields as $index => $field ) {
			// Generate name from label if not present.
			$label       = $field['label'] ?? '';
			$label_lower = strtolower( $label );
			$field_type  = $field['type'] ?? 'text';

			// Map common label variations to canonical core field names.
			// This ensures "E-Mail" becomes "email", "Telefon" becomes "phone", etc.
			// Note: Only match by LABEL, not by type, to avoid mapping multiple fields.
			// (e.g., "Mobil" with type=tel should NOT become "phone" core field).
			$core_name = null;
			if ( in_array( $label_lower, array( 'name' ), true ) ) {
				$core_name = 'name';
			} elseif ( in_array( $label_lower, array( 'e-mail', 'email' ), true ) ) {
				$core_name = 'email';
			} elseif ( in_array( $label_lower, array( 'telefon', 'phone' ), true ) ) {
				$core_name = 'phone';
			}

			// Use explicit name if set, otherwise use canonical core name or generate from label.
			if ( isset( $field['name'] ) && '' !== $field['name'] ) {
				$name = $field['name'];
			} elseif ( null !== $core_name ) {
				$name = $core_name;
			} else {
				$name = sanitize_key( $label );
			}

			// Parse options - support comma, newline separated, or already an array.
			$options_raw = $field['options'] ?? '';
			$options     = array();

			if ( is_array( $options_raw ) ) {
				// Already an array - but might contain comma-separated strings.
				foreach ( $options_raw as $opt ) {
					if ( is_string( $opt ) && strpos( $opt, ',' ) !== false ) {
						// Split comma-separated values within array element.
						$sub_opts = array_map( 'trim', explode( ',', $opt ) );
						$options  = array_merge( $options, $sub_opts );
					} else {
						$options[] = trim( (string) $opt );
					}
				}
			} elseif ( ! empty( $options_raw ) && is_string( $options_raw ) ) {
				// First try newline, then comma.
				if ( strpos( $options_raw, "\n" ) !== false ) {
					$options = array_map( 'trim', explode( "\n", $options_raw ) );
				} else {
					$options = array_map( 'trim', explode( ',', $options_raw ) );
				}
			}

			// Filter empty values.
			$options = array_filter( $options, fn( $opt ) => '' !== $opt );

			// Condition format: "field_name:value" (e.g., "ich_benoetige_eine_gastbox:Ja").
			$condition = $field['condition'] ?? '';

			// Check if this is a core field.
			$is_core      = isset( self::$core_fields[ $name ] );
			$autocomplete = $is_core ? self::$core_fields[ $name ]['autocomplete'] : '';

			// For core fields, use their defined type.
			$field_type = $field['type'] ?? 'text';
			if ( $is_core && isset( self::$core_fields[ $name ]['type'] ) ) {
				$field_type = self::$core_fields[ $name ]['type'];
			}

			$normalized[] = array(
				'name'         => $name,
				'label'        => $label,
				'type'         => $field_type,
				'required'     => ! empty( $field['mandatory'] ) || ! empty( $field['required'] ),
				'options'      => implode( "\n", $options ), // Store as newline-separated for template.
				'page'         => $field['page'] ?? '',      // For agreement type links.
				'condition'    => $condition,                // Conditional display: "field_name:value".
				'core'         => $is_core,                  // Core fields use name="fieldname" directly.
				'autocomplete' => $autocomplete,             // Autocomplete attribute for core fields.
				'half_width'   => ! empty( $field['half_width'] ), // 50% width display.
				'width'        => $field['width'] ?? 0,      // Custom width percentage.
				'active'       => $field['active'] ?? true,  // Field is active/visible.
			);
		}

		return $normalized;
	}

	/**
	 * Initialize default booking fields if not present.
	 *
	 * Ensures core fields (Name, Email, Phone) exist in the database.
	 * Call this on plugin activation or settings page load.
	 *
	 * @return bool True if fields were added, false if already present.
	 */
	public static function init_default_booking_fields(): bool {
		$data = get_option( 'kurs_booking_custom_fields', '' );

		// Handle both array (from update_option) and JSON string formats.
		if ( is_array( $data ) ) {
			$fields = $data;
		} elseif ( ! empty( $data ) && is_string( $data ) ) {
			$fields = json_decode( $data, true ) ?: array();
		} else {
			$fields = array();
		}

		if ( ! is_array( $fields ) ) {
			$fields = array();
		}

		// Check which core fields exist.
		$has_name  = false;
		$has_email = false;
		$has_phone = false;

		foreach ( $fields as $field ) {
			$field_name  = $field['name'] ?? '';
			$field_label = strtolower( $field['label'] ?? '' );
			$field_type  = $field['type'] ?? '';

			// Check by name, label, or type.
			if ( 'name' === $field_name || 'name' === $field_label ) {
				$has_name = true;
			} elseif ( 'email' === $field_name || 'e-mail' === $field_label || 'email' === $field_type ) {
				$has_email = true;
			} elseif ( 'phone' === $field_name || 'telefon' === $field_label || 'tel' === $field_type ) {
				$has_phone = true;
			}
		}

		// If all core fields exist, nothing to do.
		if ( $has_name && $has_email && $has_phone ) {
			return false;
		}

		// Add missing core fields at the beginning.
		$core_fields = array();

		if ( ! $has_name ) {
			$core_fields[] = array(
				'name'      => 'name',
				'label'     => __( 'Name', 'kurs-booking' ),
				'type'      => 'text',
				'mandatory' => true,
				'options'   => '',
				'page'      => '',
				'condition' => '',
			);
		}

		if ( ! $has_email ) {
			$core_fields[] = array(
				'name'      => 'email',
				'label'     => __( 'E-Mail', 'kurs-booking' ),
				'type'      => 'email',
				'mandatory' => true,
				'options'   => '',
				'page'      => '',
				'condition' => '',
			);
		}

		if ( ! $has_phone ) {
			$core_fields[] = array(
				'name'      => 'phone',
				'label'     => __( 'Telefon', 'kurs-booking' ),
				'type'      => 'tel',
				'mandatory' => false,
				'options'   => '',
				'page'      => '',
				'condition' => '',
			);
		}

		// Merge: core fields first, then existing fields.
		$fields = array_merge( $core_fields, $fields );

		// Save to database.
		update_option( 'kurs_booking_custom_fields', wp_json_encode( $fields ) );

		return true;
	}

	/**
	 * Get cancellation text preview
	 *
	 * @return string Generated cancellation text.
	 */
	private static function get_cancellation_text_preview(): string {
		$custom = get_option( 'kurs_booking_cancel_custom_text', '' );
		if ( ! empty( $custom ) ) {
			return $custom;
		}

		$free    = (int) get_option( 'kurs_booking_cancel_free_days', 28 );
		$partial = (int) get_option( 'kurs_booking_cancel_partial_days', 14 );
		$percent = (int) get_option( 'kurs_booking_cancel_partial_percent', 50 );

		return sprintf(
			"• Bis %d Tage vor Kursbeginn: kostenfrei\n• Bis %d Tage vor Kursbeginn: %d%% der Kursgebühr\n• Weniger als %d Tage vorher: 100%% der Kursgebühr\n\nEine Stornierung ist nur schriftlich per E-Mail möglich.",
			$free,
			$partial,
			$percent,
			$partial
		);
	}

	/**
	 * Get default withdrawal notice
	 *
	 * @return string Default withdrawal notice text.
	 */
	private static function get_default_withdrawal_notice(): string {
		return 'Gemäß § 312g Abs. 2 Nr. 9 BGB besteht bei Dienstleistungen im Bereich Freizeitbetätigungen (hier: Reitkurs) zu einem spezifischen Termin kein gesetzliches Widerrufsrecht.';
	}

	/**
	 * Get default AGB checkbox text
	 *
	 * @return string Default AGB checkbox text.
	 */
	private static function get_default_agb_checkbox_text(): string {
		return 'Ich akzeptiere die [AGB] und habe die Stornobedingungen sowie die Widerrufsbelehrung zur Kenntnis genommen.';
	}

	/**
	 * Generate a unique field name from label.
	 *
	 * Converts label to a slug-like name (lowercase, underscores, ASCII only).
	 * Ensures uniqueness by appending a number if needed.
	 *
	 * @param string              $label  The field label.
	 * @param array<array<mixed>> $existing_fields Existing fields to check for uniqueness.
	 * @return string The generated unique field name.
	 */
	private static function generate_field_name( string $label, array $existing_fields ): string {
		// Convert to lowercase, replace spaces/special chars with underscore.
		$name = strtolower( $label );

		// Replace German umlauts.
		$replacements = array(
			'ä' => 'ae',
			'ö' => 'oe',
			'ü' => 'ue',
			'ß' => 'ss',
			'Ä' => 'ae',
			'Ö' => 'oe',
			'Ü' => 'ue',
		);
		$name = strtr( $name, $replacements );

		// Replace non-alphanumeric with underscore, collapse multiple underscores.
		$name = preg_replace( '/[^a-z0-9]+/', '_', $name );
		$name = trim( $name, '_' );

		// Fallback if empty.
		if ( empty( $name ) ) {
			$name = 'field';
		}

		// Ensure uniqueness.
		$existing_names = array_column( $existing_fields, 'name' );
		$base_name      = $name;
		$counter        = 1;
		while ( in_array( $name, $existing_names, true ) ) {
			$name = $base_name . '_' . $counter;
			++$counter;
		}

		return $name;
	}

	/**
	 * Get cancellation text for emails and booking
	 *
	 * @return string Cancellation text.
	 */
	public static function get_cancellation_text(): string {
		return self::get_cancellation_text_preview();
	}

	/**
	 * Get bank data
	 *
	 * @return array<string, string> Bank data array.
	 */
	public static function get_bank_data(): array {
		return array(
			'holder'    => get_option( 'kurs_booking_bank_account_holder', get_option( 'kurs_booking_company_name', '' ) ),
			'iban'      => get_option( 'kurs_booking_bank_iban', '' ),
			'bic'       => get_option( 'kurs_booking_bank_bic', '' ),
			'bank_name' => get_option( 'kurs_booking_bank_name', '' ),
		);
	}

	/**
	 * Get sevDesk settings
	 *
	 * @return array<string, mixed> sevDesk settings array.
	 */
	public static function get_sevdesk_settings(): array {
		return array(
			'api_token'         => get_option( 'kurs_booking_sevdesk_api_token', '' ),
			'user_id'           => (int) get_option( 'kurs_booking_sevdesk_user_id', 0 ),
			'contact_category'  => (int) get_option( 'kurs_booking_sevdesk_contact_category', 0 ),
			'auto_invoice'      => (bool) get_option( 'kurs_booking_sevdesk_auto_invoice', true ),
			'auto_send_invoice' => (bool) get_option( 'kurs_booking_sevdesk_auto_send_invoice', false ),
			'invoice_status'    => (int) get_option( 'kurs_booking_sevdesk_invoice_status', 100 ),
			'position_text'     => get_option( 'kurs_booking_sevdesk_position_text', '{kurs_name} (Buchung: {buchungs_nummer})' ),
			'category_id'       => (int) get_option( 'kurs_booking_sevdesk_contact_category', 3 ),
		);
	}

	/**
	 * Build invoice position text from template
	 *
	 * @param int $buchung_id Booking ID.
	 * @return string Formatted position text.
	 */
	public static function build_invoice_position_text( int $buchung_id ): string {
		$template = get_option( 'kurs_booking_sevdesk_position_text', '{kurs_name} (Buchung: {buchungs_nummer})' );

		$kurs_id         = Kurs_Booking_Buchung::get_meta( $buchung_id, 'kurs_id', 0 );
		$buchungs_nummer = Kurs_Booking_Buchung::get_meta( $buchung_id, 'buchungs_nummer', '' );
		$tickets         = Kurs_Booking_Buchung::get_meta( $buchung_id, 'tickets', 1 );
		$kurs_name       = get_the_title( $kurs_id );

		// Get event date from kurs meta.
		$kurs_datum = get_post_meta( $kurs_id, '_kurs_datum', true );
		$datum      = $kurs_datum ? date_i18n( 'd.m.Y', strtotime( $kurs_datum ) ) : '';

		// Sprint 8.4: Get produktart data for sevDesk placeholders.
		$produktart_id    = '';
		$produktart_name  = '';
		$produktart_label = '';
		if ( $kurs_id > 0 && class_exists( 'Kurs_Booking_Dienstleistungen' ) ) {
			$produktart_id = Kurs_Booking_Kurs::get_meta( $kurs_id, 'produktart', 'kurs' );
			$dl            = Kurs_Booking_Dienstleistungen::get( $produktart_id );
			if ( $dl ) {
				$produktart_name  = $dl['name'] ?? '';
				$produktart_label = Kurs_Booking_Dienstleistungen::get_label( $produktart_id );
			}
		}

		$replacements = array(
			'{kurs_name}'       => $kurs_name,
			'{buchungs_nummer}' => $buchungs_nummer,
			'{datum}'           => $datum,
			'{tickets}'         => (string) $tickets,
			// Sprint 8.4: Produktart-Platzhalter für sevDesk.
			'{produktart}'      => $produktart_label,       // "A) Präsenz-Kurs".
			'{produktart_name}' => $produktart_name,        // "Präsenz-Kurs".
			'{produktart_id}'   => $produktart_id,          // "kurs".
		);

		return str_replace( array_keys( $replacements ), array_values( $replacements ), $template );
	}

	/**
	 * Get booking settings
	 *
	 * @return array<string, mixed> Booking settings array.
	 */
	public static function get_booking_settings(): array {
		return array(
			'number_prefix'           => get_option( 'kurs_booking_number_prefix', 'BK' ),
			'next_number'             => (int) get_option( 'kurs_booking_next_number', 1 ),
			'confirm_validity_hours'  => (int) get_option( 'kurs_booking_confirm_validity_hours', 48 ),
			'default_ticket_name'     => get_option( 'kurs_booking_default_ticket_name', 'Ticket' ),
			'admin_email'             => get_option( 'kurs_booking_admin_email', get_option( 'admin_email' ) ),
			'bcc_admin'               => (bool) get_option( 'kurs_booking_bcc_admin', true ),
			'max_tickets'             => (int) get_option( 'kurs_booking_max_tickets', 10 ),
		);
	}

	/**
	 * Get price/VAT settings
	 *
	 * @return array<string, mixed> Price settings array.
	 */
	public static function get_price_settings(): array {
		return array(
			'price_display'           => get_option( 'kurs_booking_price_display', 'gross' ),
			'vat_rate'                => (float) get_option( 'kurs_booking_vat_rate', 19.0 ),
			'small_business'          => (bool) get_option( 'kurs_booking_small_business', false ),
			'currency_symbol'         => get_option( 'kurs_booking_currency_symbol', '€' ),
			'currency_position'       => get_option( 'kurs_booking_currency_position', 'after' ),
			'decimal_separator'       => get_option( 'kurs_booking_decimal_separator', ',' ),
			'thousand_separator'      => get_option( 'kurs_booking_thousand_separator', '.' ),
			'decimals'                => (int) get_option( 'kurs_booking_decimals', 2 ),
			'default_deposit_percent' => (int) get_option( 'kurs_booking_default_deposit_percent', 0 ),
		);
	}

	/**
	 * Format price according to settings
	 *
	 * @param float $price Price to format.
	 * @param bool  $include_symbol Include currency symbol.
	 * @return string Formatted price.
	 */
	public static function format_price( float $price, bool $include_symbol = true ): string {
		$settings = self::get_price_settings();

		$formatted = number_format(
			$price,
			$settings['decimals'],
			$settings['decimal_separator'],
			$settings['thousand_separator']
		);

		if ( ! $include_symbol ) {
			return $formatted;
		}

		if ( 'before' === $settings['currency_position'] ) {
			return $settings['currency_symbol'] . ' ' . $formatted;
		}

		return $formatted . ' ' . $settings['currency_symbol'];
	}

	/**
	 * Calculate net price from gross
	 *
	 * @param float $gross Gross price.
	 * @return float Net price.
	 */
	public static function calculate_net_from_gross( float $gross ): float {
		$settings = self::get_price_settings();

		if ( $settings['small_business'] ) {
			return $gross;
		}

		$vat_rate = $settings['vat_rate'] / 100;
		return round( $gross / ( 1 + $vat_rate ), 2 );
	}

	/**
	 * Calculate gross price from net
	 *
	 * @param float $net Net price.
	 * @return float Gross price.
	 */
	public static function calculate_gross_from_net( float $net ): float {
		$settings = self::get_price_settings();

		if ( $settings['small_business'] ) {
			return $net;
		}

		$vat_rate = $settings['vat_rate'] / 100;
		return round( $net * ( 1 + $vat_rate ), 2 );
	}

	/**
	 * Calculate VAT amount
	 *
	 * @param float $gross Gross price.
	 * @return float VAT amount.
	 */
	public static function calculate_vat_amount( float $gross ): float {
		$settings = self::get_price_settings();

		if ( $settings['small_business'] ) {
			return 0.0;
		}

		$net = self::calculate_net_from_gross( $gross );
		return round( $gross - $net, 2 );
	}

	/**
	 * Get next booking number and increment
	 *
	 * @return string Formatted booking number.
	 */
	public static function get_next_booking_number(): string {
		$prefix = get_option( 'kurs_booking_number_prefix', 'BK' );
		$number = (int) get_option( 'kurs_booking_next_number', 1 );
		$year   = gmdate( 'Y' );

		// Increment for next use.
		update_option( 'kurs_booking_next_number', $number + 1 );

		return sprintf( '%s-%s-%04d', $prefix, $year, $number );
	}

	/**
	 * Get legal settings
	 *
	 * @return array<string, mixed> Legal settings array.
	 */
	public static function get_legal_settings(): array {
		return array(
			'agb_page_id'        => (int) get_option( 'kurs_booking_agb_page_id', 0 ),
			'privacy_page_id'    => (int) get_option( 'kurs_booking_privacy_page_id', 0 ),
			'withdrawal_notice'  => get_option( 'kurs_booking_withdrawal_notice', self::get_default_withdrawal_notice() ),
			'agb_checkbox_text'  => get_option( 'kurs_booking_agb_checkbox_text', self::get_default_agb_checkbox_text() ),
		);
	}

	/**
	 * Get AGB checkbox HTML with links
	 *
	 * @return string Checkbox text with links.
	 */
	public static function get_agb_checkbox_html(): string {
		$settings = self::get_legal_settings();
		$text     = $settings['agb_checkbox_text'];

		// Replace [AGB] with link.
		if ( $settings['agb_page_id'] > 0 ) {
			$agb_url = get_permalink( $settings['agb_page_id'] );
			$text    = str_replace( '[AGB]', '<a href="' . esc_url( $agb_url ) . '" target="_blank">AGB</a>', $text );
		} else {
			$text = str_replace( '[AGB]', 'AGB', $text );
		}

		// Replace [Datenschutz] with link.
		if ( $settings['privacy_page_id'] > 0 ) {
			$privacy_url = get_permalink( $settings['privacy_page_id'] );
			$text        = str_replace( '[Datenschutz]', '<a href="' . esc_url( $privacy_url ) . '" target="_blank">Datenschutzerklärung</a>', $text );
		} else {
			$text = str_replace( '[Datenschutz]', 'Datenschutzerklärung', $text );
		}

		return $text;
	}

	/**
	 * Get email template types configuration
	 *
	 * @return array<string, array<string, mixed>> Template types with labels and variables.
	 */
	public static function get_email_template_types(): array {
		return array(
			'booking_received' => array(
				'label'     => __( 'Buchungseingang', 'kurs-booking' ),
				'desc'      => __( 'Double-Opt-In E-Mail nach Buchungsanfrage', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'   => __( 'Kundenname', 'kurs-booking' ),
					'{{customer_email}}'  => __( 'E-Mail-Adresse', 'kurs-booking' ),
					'{{buchung_nummer}}'  => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{kurs_title}}'      => __( 'Kursname', 'kurs-booking' ),
					'{{kurs_date}}'       => __( 'Kursdatum', 'kurs-booking' ),
					'{{kurs_start}}'      => __( 'Startzeit', 'kurs-booking' ),
					'{{kurs_location}}'   => __( 'Veranstaltungsort', 'kurs-booking' ),
					'{{total_price}}'     => __( 'Gesamtpreis', 'kurs-booking' ),
					'{{confirm_url}}'     => __( 'Bestätigungslink', 'kurs-booking' ),
					'{{company_name}}'    => __( 'Firmenname', 'kurs-booking' ),
				),
			),
			'booking_confirmed' => array(
				'label'     => __( 'Buchungsbestätigung', 'kurs-booking' ),
				'desc'      => __( 'Bestätigung nach erfolgreicher Buchung', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'   => __( 'Kundenname', 'kurs-booking' ),
					'{{customer_email}}'  => __( 'E-Mail-Adresse', 'kurs-booking' ),
					'{{customer_phone}}'  => __( 'Telefon', 'kurs-booking' ),
					'{{buchung_nummer}}'  => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{buchung_date}}'    => __( 'Buchungsdatum', 'kurs-booking' ),
					'{{kurs_title}}'      => __( 'Kursname', 'kurs-booking' ),
					'{{kurs_date}}'       => __( 'Kursdatum', 'kurs-booking' ),
					'{{kurs_start}}'      => __( 'Startzeit', 'kurs-booking' ),
					'{{kurs_end}}'        => __( 'Endzeit', 'kurs-booking' ),
					'{{kurs_location}}'   => __( 'Veranstaltungsort', 'kurs-booking' ),
					'{{kurs_address}}'    => __( 'Adresse', 'kurs-booking' ),
					'{{total_price}}'     => __( 'Gesamtpreis', 'kurs-booking' ),
					'{{deposit_amount}}'  => __( 'Anzahlung', 'kurs-booking' ),
					'{{cancel_url}}'      => __( 'Storno-Link', 'kurs-booking' ),
					'{{company_name}}'    => __( 'Firmenname', 'kurs-booking' ),
					'{{company_iban}}'    => __( 'IBAN', 'kurs-booking' ),
				),
			),
			'cancellation_confirmation' => array(
				'label'     => __( 'Stornierungsbestätigung', 'kurs-booking' ),
				'desc'      => __( 'E-Mail an Kunde bei Stornierung', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'       => __( 'Kundenname', 'kurs-booking' ),
					'{{buchung_nummer}}'      => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{kurs_title}}'          => __( 'Kursname', 'kurs-booking' ),
					'{{kurs_date}}'           => __( 'Kursdatum', 'kurs-booking' ),
					'{{total_price}}'         => __( 'Urspr. Buchungsbetrag', 'kurs-booking' ),
					'{{cancel_date}}'         => __( 'Stornierungsdatum', 'kurs-booking' ),
					'{{cancel_fee_percent}}'  => __( 'Stornogebühr %', 'kurs-booking' ),
					'{{cancel_fee_amount}}'   => __( 'Stornogebühr EUR', 'kurs-booking' ),
					'{{cancel_refund_amount}}' => __( 'Rückerstattung', 'kurs-booking' ),
					'{{company_name}}'        => __( 'Firmenname', 'kurs-booking' ),
				),
			),
			'admin_notification' => array(
				'label'     => __( 'Admin: Neue Buchung', 'kurs-booking' ),
				'desc'      => __( 'Benachrichtigung an Admin bei neuer Buchung', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'   => __( 'Kundenname', 'kurs-booking' ),
					'{{customer_email}}'  => __( 'E-Mail-Adresse', 'kurs-booking' ),
					'{{customer_phone}}'  => __( 'Telefon', 'kurs-booking' ),
					'{{buchung_nummer}}'  => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{kurs_title}}'      => __( 'Kursname', 'kurs-booking' ),
					'{{kurs_date}}'       => __( 'Kursdatum', 'kurs-booking' ),
					'{{total_price}}'     => __( 'Gesamtpreis', 'kurs-booking' ),
					'{{edit_url}}'        => __( 'Buchung bearbeiten URL', 'kurs-booking' ),
				),
			),
			'admin_cancellation' => array(
				'label'     => __( 'Admin: Stornierung', 'kurs-booking' ),
				'desc'      => __( 'Benachrichtigung an Admin bei Stornierung', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'       => __( 'Kundenname', 'kurs-booking' ),
					'{{customer_email}}'      => __( 'E-Mail-Adresse', 'kurs-booking' ),
					'{{buchung_nummer}}'      => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{kurs_title}}'          => __( 'Kursname', 'kurs-booking' ),
					'{{total_price}}'         => __( 'Buchungsbetrag', 'kurs-booking' ),
					'{{cancel_fee_amount}}'   => __( 'Stornogebühr', 'kurs-booking' ),
					'{{cancel_refund_amount}}' => __( 'Zu erstatten', 'kurs-booking' ),
					'{{cancel_reason}}'       => __( 'Stornierungsgrund', 'kurs-booking' ),
					'{{edit_url}}'            => __( 'Buchung bearbeiten URL', 'kurs-booking' ),
				),
			),
			'video_access' => array(
				'label'     => __( 'Video-Zugang', 'kurs-booking' ),
				'desc'      => __( 'E-Mail mit Video-Link nach Zahlungseingang', 'kurs-booking' ),
				'variables' => array(
					'{{customer_name}}'  => __( 'Kundenname', 'kurs-booking' ),
					'{{buchung_nummer}}' => __( 'Buchungsnummer', 'kurs-booking' ),
					'{{kurs_title}}'     => __( 'Kursname', 'kurs-booking' ),
					'{{video_url}}'      => __( 'Video-Link', 'kurs-booking' ),
					'{{company_name}}'   => __( 'Firmenname', 'kurs-booking' ),
				),
			),
		);
	}

	/**
	 * Render email templates settings tab
	 */
	private static function render_email_templates_tab(): void {
		$template_types = self::get_email_template_types();

		// Get current sub-tab.
        // phpcs:ignore WordPress.Security.NonceVerification.Recommended
		$current_template = isset( $_GET['template'] ) ? sanitize_key( $_GET['template'] ) : 'booking_received';

		if ( ! isset( $template_types[ $current_template ] ) ) {
			$current_template = 'booking_received';
		}

		$config = $template_types[ $current_template ];

		?>
		<h2><?php esc_html_e( 'E-Mail Vorlagen', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Passen Sie die E-Mail-Vorlagen an Ihre Bedürfnisse an. Verwenden Sie die Variablen-Palette um dynamische Inhalte einzufügen.', 'kurs-booking' ); ?>
		</p>

		<!-- Sub-Tab Navigation -->
		<nav class="nav-tab-wrapper kurs-booking-email-subtabs" style="margin: 20px 0;">
			<?php foreach ( $template_types as $type => $tpl_config ) : ?>
				<?php
				$url = add_query_arg(
					array(
						'page'     => 'kurs-booking-settings',
						'tab'      => 'email_templates',
						'template' => $type,
					),
					admin_url( 'admin.php' )
				);
				?>
				<a href="<?php echo esc_url( $url ); ?>"
				   class="nav-tab <?php echo $current_template === $type ? 'nav-tab-active' : ''; ?>">
					<?php echo esc_html( $tpl_config['label'] ); ?>
				</a>
			<?php endforeach; ?>
		</nav>

		<div class="kurs-booking-email-template-editor">
			<h3><?php echo esc_html( $config['label'] ); ?></h3>
			<p class="description"><?php echo esc_html( $config['desc'] ); ?></p>

			<!-- Variables Palette -->
			<div class="kurs-booking-variables-palette" style="background: #f0f0f1; padding: 15px; border-radius: 4px; margin: 20px 0;">
				<h4 style="margin-top: 0;">
					<?php esc_html_e( 'Verfügbare Variablen', 'kurs-booking' ); ?>
					<span class="description" style="font-weight: normal;">
						(<?php esc_html_e( 'Klicken zum Einfügen', 'kurs-booking' ); ?>)
					</span>
				</h4>
				<div class="kurs-booking-variables-list" style="display: flex; flex-wrap: wrap; gap: 8px;">
					<?php foreach ( $config['variables'] as $var => $label ) : ?>
						<button type="button"
								class="button kurs-booking-variable-btn"
								data-variable="<?php echo esc_attr( $var ); ?>"
								title="<?php echo esc_attr( $label ); ?>">
							<?php echo esc_html( $var ); ?>
						</button>
					<?php endforeach; ?>
				</div>
			</div>

			<table class="form-table">
				<!-- Subject -->
				<tr>
					<th scope="row">
						<label for="kurs_booking_email_tpl_<?php echo esc_attr( $current_template ); ?>_subject">
							<?php esc_html_e( 'Betreff', 'kurs-booking' ); ?>
						</label>
					</th>
					<td>
						<?php
						$subject_key     = 'kurs_booking_email_tpl_' . $current_template . '_subject';
						$default_subject = self::get_default_email_subject( $current_template );
						$saved_subject   = get_option( $subject_key, '' );
						?>
						<input type="text"
							   name="<?php echo esc_attr( $subject_key ); ?>"
							   id="<?php echo esc_attr( $subject_key ); ?>"
							   value="<?php echo esc_attr( $saved_subject ); ?>"
							   placeholder="<?php echo esc_attr( $default_subject ); ?>"
							   class="large-text kurs-booking-email-subject">
						<p class="description">
							<?php esc_html_e( 'Leer lassen für Standard-Betreff:', 'kurs-booking' ); ?>
							<code><?php echo esc_html( $default_subject ); ?></code>
						</p>
					</td>
				</tr>

				<!-- Body -->
				<tr>
					<th scope="row">
						<label for="kurs_booking_email_tpl_<?php echo esc_attr( $current_template ); ?>_body">
							<?php esc_html_e( 'Inhalt', 'kurs-booking' ); ?>
						</label>
					</th>
					<td>
						<?php
						$body_key   = 'kurs_booking_email_tpl_' . $current_template . '_body';
						$saved_body = get_option( $body_key, '' );

						wp_editor(
							$saved_body,
							'kurs_booking_email_tpl_' . $current_template . '_body',
							array(
								'textarea_name' => $body_key,
								'textarea_rows' => 20,
								'media_buttons' => false,
								'teeny'         => false,
								'quicktags'     => true,
							)
						);
						?>
						<p class="description">
							<?php esc_html_e( 'Leer lassen für Standard-Template. HTML wird unterstützt.', 'kurs-booking' ); ?>
						</p>
					</td>
				</tr>
			</table>

			<!-- Action Buttons -->
			<div class="kurs-booking-template-actions" style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #ddd;">
				<button type="button"
						class="button kurs-booking-preview-email"
						data-template="<?php echo esc_attr( $current_template ); ?>">
					<?php esc_html_e( 'Vorschau', 'kurs-booking' ); ?>
				</button>
				<button type="button"
						class="button kurs-booking-reset-template"
						data-template="<?php echo esc_attr( $current_template ); ?>"
						style="color: #b32d2e;">
					<?php esc_html_e( 'Auf Standard zurücksetzen', 'kurs-booking' ); ?>
				</button>
				<button type="button"
						class="button kurs-booking-load-default-template"
						data-template="<?php echo esc_attr( $current_template ); ?>"
						style="margin-left: auto;">
					<?php esc_html_e( 'Standard-Vorlage laden', 'kurs-booking' ); ?>
				</button>
			</div>

			<!-- MEC Import (only show once at the bottom) -->
			<?php if ( 'booking_received' === $current_template ) : ?>
			<div class="kurs-booking-mec-import" style="margin-top: 30px; padding: 20px; background: #e8f4fd; border: 1px solid #007bff; border-radius: 4px;">
				<h4 style="margin-top: 0;"><?php esc_html_e( 'MEC Templates importieren', 'kurs-booking' ); ?></h4>
				<p class="description">
					<?php esc_html_e( 'Importiert die E-Mail-Vorlagen aus dem Modern Events Calendar (MEC) und konvertiert die Platzhalter automatisch.', 'kurs-booking' ); ?>
				</p>
				<button type="button"
						class="button button-primary kurs-booking-import-mec-templates"
						style="margin-top: 10px;">
					<?php esc_html_e( 'Von MEC importieren', 'kurs-booking' ); ?>
				</button>
				<span class="kurs-booking-import-result" style="margin-left: 10px;"></span>
			</div>
			<?php endif; ?>
		</div>
		<?php
	}

	/**
	 * Get default email subject for template type
	 *
	 * @param string $template_type Template type.
	 * @return string Default subject.
	 */
	public static function get_default_email_subject( string $template_type ): string {
		$subjects = array(
			'booking_received'          => __( 'Buchungsanfrage eingegangen - Bitte bestätigen Sie Ihre Email [{{buchung_nummer}}]', 'kurs-booking' ),
			'booking_confirmed'         => __( 'Buchungsbestätigung Nr. {{buchung_nummer}} – {{kurs_title}}', 'kurs-booking' ),
			'cancellation_confirmation' => __( 'Stornierungsbestätigung – Buchung {{buchung_nummer}}', 'kurs-booking' ),
			'admin_notification'        => __( 'Neue Buchung: {{buchung_nummer}} – {{kurs_title}}', 'kurs-booking' ),
			'admin_cancellation'        => __( 'Stornierung: {{buchung_nummer}} – {{kurs_title}}', 'kurs-booking' ),
			'video_access'              => __( 'Ihr Video-Zugang – {{kurs_title}}', 'kurs-booking' ),
		);

		return $subjects[ $template_type ] ?? '';
	}

	/**
	 * Get custom email template if exists
	 *
	 * @param string $template_type Template type (e.g., 'booking_received').
	 * @return array{subject: string, body: string}|null Template data or null if not customized.
	 */
	public static function get_custom_email_template( string $template_type ): ?array {
		$subject = get_option( 'kurs_booking_email_tpl_' . $template_type . '_subject', '' );
		$body    = get_option( 'kurs_booking_email_tpl_' . $template_type . '_body', '' );

		// Return null if both are empty (use default).
		if ( empty( $subject ) && empty( $body ) ) {
			return null;
		}

		return array(
			'subject' => $subject,
			'body'    => $body,
		);
	}

	/**
	 * Process template variables in content
	 *
	 * @param string               $content Template content.
	 * @param array<string, mixed> $data    Data array with variable values.
	 * @return string Processed content.
	 */
	public static function process_email_template_variables( string $content, array $data ): string {
		$replacements = array(
			// Customer.
			'{{customer_name}}'   => $data['customer_name'] ?? '',
			'{{customer_email}}'  => $data['customer_email'] ?? '',
			'{{customer_phone}}'  => $data['customer_phone'] ?? '',

			// Booking.
			'{{buchung_nummer}}'  => $data['buchung_nummer'] ?? '',
			'{{buchung_date}}'    => $data['buchung_date'] ?? '',
			'{{total_price}}'     => isset( $data['total_price'] ) ? self::format_price( (float) $data['total_price'] ) : '',
			'{{deposit_amount}}'  => isset( $data['deposit_amount'] ) ? self::format_price( (float) $data['deposit_amount'] ) : '',

			// Course.
			'{{kurs_title}}'      => $data['kurs_title'] ?? '',
			'{{kurs_date}}'       => $data['kurs_date'] ?? '',
			'{{kurs_start}}'      => $data['kurs_start'] ?? '',
			'{{kurs_end}}'        => $data['kurs_end'] ?? '',
			'{{kurs_location}}'   => $data['kurs_location'] ?? '',
			'{{kurs_address}}'    => $data['kurs_address'] ?? '',

			// URLs.
			'{{confirm_url}}'     => $data['confirm_url'] ?? '',
			'{{cancel_url}}'      => $data['cancel_url'] ?? '',
			'{{edit_url}}'        => $data['edit_url'] ?? '',
			'{{video_url}}'       => $data['video_url'] ?? '',

			// Cancellation.
			'{{cancel_date}}'         => $data['cancel_date'] ?? '',
			'{{cancel_fee_percent}}'  => $data['cancel_fee_percent'] ?? '',
			'{{cancel_fee_amount}}'   => isset( $data['cancel_fee_amount'] ) ? self::format_price( (float) $data['cancel_fee_amount'] ) : '',
			'{{cancel_refund_amount}}' => isset( $data['cancel_refund_amount'] ) ? self::format_price( (float) $data['cancel_refund_amount'] ) : '',
			'{{cancel_reason}}'       => $data['cancel_reason'] ?? '',

			// Company.
			'{{company_name}}'    => get_option( 'kurs_booking_company_name', '' ),
			'{{company_email}}'   => get_option( 'kurs_booking_company_email', '' ),
			'{{company_phone}}'   => get_option( 'kurs_booking_company_phone', '' ),
			'{{company_website}}' => get_option( 'kurs_booking_company_website', '' ),
			'{{company_iban}}'    => get_option( 'kurs_booking_bank_iban', '' ),
		);

		return str_replace( array_keys( $replacements ), array_values( $replacements ), $content );
	}

	/**
	 * Get default email template body.
	 *
	 * Based on MEC (Modern Events Calendar) templates, adapted for Kurs-Booking.
	 *
	 * @param string $template_type Template type.
	 * @return string Default HTML body.
	 */
	public static function get_default_email_body( string $template_type ): string {
		$templates = array(
			// Double-Opt-In / Email Verification.
			'booking_received' => '
<p>Liebe(r) {{customer_name}},</p>

<p>Bitte bestätige deine E-Mail-Adresse, indem du auf den folgenden Link klickst:</p>

<p><a href="{{confirm_url}}" style="display: inline-block; background-color: #007bff; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-weight: bold;">E-Mail bestätigen</a></p>

<p>Oder kopiere diesen Link in deinen Browser:<br>
{{confirm_url}}</p>

<p><strong>Sobald deine E-Mail-Adresse bestätigt wurde, erhältst du eine Buchungsbestätigung.</strong></p>

<p>Herzliche Grüße<br>
{{company_name}}</p>
',
			// Booking Confirmation.
			'booking_confirmed' => '
<p>Liebe(r) {{customer_name}},</p>

<p>Deine Buchung für folgende Veranstaltung "<strong>{{kurs_title}}</strong>" wird hiermit bestätigt.</p>

<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Buchungsnummer:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold;">{{buchung_nummer}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Veranstaltung:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold;">{{kurs_title}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Datum:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd;">{{kurs_date}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Uhrzeit:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd;">{{kurs_start}} Uhr</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Ort:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd;">{{kurs_location}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Gesamtpreis:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold;">{{total_price}}</td>
    </tr>
</table>

<p>Falls du die Buchung stornieren möchtest, klicke hier:<br>
<a href="{{cancel_url}}">Buchung stornieren</a></p>

<p>Herzliche Grüße<br>
{{company_name}}</p>
',
			// Cancellation Confirmation (Customer).
			'cancellation_confirmation' => '
<p>Liebe(r) {{customer_name}},</p>

<p>Deine Buchung für "<strong>{{kurs_title}}</strong>" wurde storniert.</p>

<table style="width: 100%; border-collapse: collapse; margin: 20px 0;">
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Buchungsnummer:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold;">{{buchung_nummer}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Stornierungsdatum:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd;">{{cancel_date}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Stornogebühr:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd;">{{cancel_fee_percent}}% = {{cancel_fee_amount}}</td>
    </tr>
    <tr>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; color: #666;">Rückerstattung:</td>
        <td style="padding: 8px; border-bottom: 1px solid #ddd; font-weight: bold; color: #28a745;">{{cancel_refund_amount}}</td>
    </tr>
</table>

<p>Die Rückerstattung wird in Kürze veranlasst.</p>

<p>Herzliche Grüße<br>
{{company_name}}</p>
',
			// Admin Notification (New Booking).
			'admin_notification' => '
<p>Hallo,</p>

<p>Eine neue Buchung ist eingegangen. Bitte überprüfen und bestätigen Sie diese.</p>

<table style="width: 100%; border-collapse: collapse; margin: 20px 0; background: #f8f9fa;">
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Buchungsnummer:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; font-weight: bold;">{{buchung_nummer}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Veranstaltung:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; font-weight: bold;">{{kurs_title}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Datum:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{kurs_date}}, {{kurs_start}} Uhr</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Kunde:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{customer_name}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">E-Mail:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;"><a href="mailto:{{customer_email}}">{{customer_email}}</a></td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Telefon:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{customer_phone}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Gesamtpreis:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; font-weight: bold;">{{total_price}}</td>
    </tr>
</table>

<p><a href="{{edit_url}}" style="display: inline-block; background-color: #007bff; color: #ffffff; padding: 10px 20px; text-decoration: none; border-radius: 4px;">Buchung anzeigen</a></p>

<p>Beste Grüße,<br>
Kurs-Booking System</p>
',
			// Admin Cancellation Notification.
			'admin_cancellation' => '
<p>Hallo,</p>

<p>Eine Buchung wurde storniert.</p>

<table style="width: 100%; border-collapse: collapse; margin: 20px 0; background: #fff3cd;">
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Buchungsnummer:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; font-weight: bold;">{{buchung_nummer}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Veranstaltung:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{kurs_title}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Kunde:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{customer_name}} ({{customer_email}})</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Storniert am:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #dc3545;">{{cancel_date}}</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Stornogebühr:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd;">{{cancel_fee_amount}} ({{cancel_fee_percent}}%)</td>
    </tr>
    <tr>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; color: #666;">Rückerstattung:</td>
        <td style="padding: 12px; border-bottom: 1px solid #ddd; font-weight: bold; color: #dc3545;">{{cancel_refund_amount}}</td>
    </tr>
</table>

<p style="color: #dc3545; font-weight: bold;">⚠️ Bitte veranlassen Sie die Rückerstattung.</p>

<p><a href="{{edit_url}}" style="display: inline-block; background-color: #6c757d; color: #ffffff; padding: 10px 20px; text-decoration: none; border-radius: 4px;">Buchung anzeigen</a></p>
',
			// Video Access.
			'video_access' => '
<p>Liebe(r) {{customer_name}},</p>

<p>Hier ist dein Zugang zum Video für "<strong>{{kurs_title}}</strong>":</p>

<p><a href="{{video_url}}" style="display: inline-block; background-color: #28a745; color: #ffffff; padding: 12px 24px; text-decoration: none; border-radius: 4px; font-weight: bold;">▶ Video ansehen</a></p>

<p>Oder kopiere diesen Link:<br>
{{video_url}}</p>

<p>Herzliche Grüße<br>
{{company_name}}</p>
',
		);

		return $templates[ $template_type ] ?? '';
	}

	/**
	 * Import MEC email templates to Kurs-Booking.
	 *
	 * Converts MEC placeholders to Kurs-Booking format and saves as custom templates.
	 *
	 * @return array<string, bool|string> Import results per template or error.
	 */
	public static function import_mec_templates(): array {
		$results = array();

		// Get MEC options.
		$mec_options = get_option( 'mec_options', array() );
		$notifications = $mec_options['notifications'] ?? array();

		if ( empty( $notifications ) ) {
			return array( 'error' => 'No MEC notifications found' );
		}

		// MEC to Kurs-Booking placeholder mapping.
		$placeholder_map = array(
			'%%name%%'                    => '{{customer_name}}',
			'%%first_name%%'              => '{{customer_name}}',
			'%%last_name%%'               => '',
			'%%user_email%%'              => '{{customer_email}}',
			'%%event_title%%'             => '{{kurs_title}}',
			'%%book_date%%'               => '{{kurs_date}}',
			'%%book_time%%'               => '{{kurs_start}}',
			'%%book_datetime%%'           => '{{kurs_date}} {{kurs_start}}',
			'%%book_price%%'              => '{{total_price}}',
			'%%book_payable%%'            => '{{total_price}}',
			'%%event_location_name%%'     => '{{kurs_location}}',
			'%%event_location_address%%'  => '{{kurs_address}}',
			'%%event_start_date%%'        => '{{kurs_date}}',
			'%%event_start_time%%'        => '{{kurs_start}}',
			'%%event_end_time%%'          => '{{kurs_end}}',
			'%%verification_link%%'       => '{{confirm_url}}',
			'%%blog_name%%'               => '{{company_name}}',
			'%%booking_id%%'              => '{{buchung_nummer}}',
		);

		// Template mapping: MEC key => Kurs-Booking key.
		$template_map = array(
			'email_verification'   => 'booking_received',
			'booking_confirmation' => 'booking_confirmed',
			'admin_notification'   => 'admin_notification',
		);

		foreach ( $template_map as $mec_key => $kb_key ) {
			if ( ! isset( $notifications[ $mec_key ] ) ) {
				$results[ $kb_key ] = false;
				continue;
			}

			$mec_notif = $notifications[ $mec_key ];

			// Convert subject.
			$subject = $mec_notif['subject'] ?? '';
			if ( ! empty( $subject ) ) {
				$subject = str_replace( array_keys( $placeholder_map ), array_values( $placeholder_map ), $subject );
				$subject = preg_replace( '/%%[^%]+%%/', '', $subject ); // Remove unmapped placeholders.
				update_option( 'kurs_booking_email_tpl_' . $kb_key . '_subject', sanitize_text_field( $subject ) );
			}

			// Convert body.
			$body = $mec_notif['content'] ?? '';
			if ( ! empty( $body ) ) {
				// Clean up MEC editor artifacts.
				$body = preg_replace( '/<span[^>]*data-mce-type="bookmark"[^>]*>.*?<\/span>/s', '', $body );
				$body = str_replace( array_keys( $placeholder_map ), array_values( $placeholder_map ), $body );
				$body = preg_replace( '/%%[^%]+%%/', '', $body ); // Remove unmapped placeholders.
				update_option( 'kurs_booking_email_tpl_' . $kb_key . '_body', wp_kses_post( $body ) );
			}

			$results[ $kb_key ] = true;
		}

		return $results;
	}

	/**
	 * Render MEC import tab
	 */
	private static function render_import_tab(): void {
		// Handle import submission.
		$import_results = null;
		if ( isset( $_POST['kurs_booking_import_nonce'] ) &&
			 wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['kurs_booking_import_nonce'] ) ), 'kurs_booking_import' ) ) {
			$import_results = self::handle_import();
		}
		?>
		<h2><?php esc_html_e( 'MEC Import', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Importieren Sie Veranstaltungen und Buchungen aus dem Modern Events Calendar (MEC).', 'kurs-booking' ); ?>
		</p>

		<?php if ( $import_results ) : ?>
			<div class="notice notice-<?php echo $import_results['success'] ? 'success' : 'error'; ?> is-dismissible">
				<p><?php echo esc_html( $import_results['message'] ); ?></p>
				<?php if ( ! empty( $import_results['details'] ) ) : ?>
					<ul style="list-style: disc; margin-left: 20px;">
						<?php foreach ( $import_results['details'] as $detail ) : ?>
							<li><?php echo esc_html( $detail ); ?></li>
						<?php endforeach; ?>
					</ul>
				<?php endif; ?>
			</div>
		<?php endif; ?>

		<div class="kurs-booking-import-container" style="margin-top: 20px;">
			<!-- Events Import -->
			<div class="card" style="max-width: 600px; margin-bottom: 20px;">
				<h3><?php esc_html_e( 'Veranstaltungen importieren', 'kurs-booking' ); ?></h3>
				<p class="description">
					<?php esc_html_e( 'Laden Sie eine JSON-Datei mit MEC-Veranstaltungen hoch.', 'kurs-booking' ); ?>
				</p>
				<form method="post" enctype="multipart/form-data">
					<?php wp_nonce_field( 'kurs_booking_import', 'kurs_booking_import_nonce' ); ?>
					<input type="hidden" name="import_type" value="events">
					<table class="form-table">
						<tr>
							<th scope="row">
								<label for="events_file"><?php esc_html_e( 'JSON-Datei', 'kurs-booking' ); ?></label>
							</th>
							<td>
								<input type="file" name="events_file" id="events_file" accept=".json">
								<p class="description">
									<?php esc_html_e( 'Exportieren Sie aus MEC: Veranstaltungen → Export → JSON Format', 'kurs-booking' ); ?>
								</p>
							</td>
						</tr>
						<tr>
							<th scope="row">
								<label for="events_dry_run">
									<input type="checkbox" name="dry_run" id="events_dry_run" value="1">
									<?php esc_html_e( 'Testlauf (keine Daten speichern)', 'kurs-booking' ); ?>
								</label>
							</th>
							<td>
								<p class="description">
									<?php esc_html_e( 'Simuliert den Import ohne Änderungen vorzunehmen.', 'kurs-booking' ); ?>
								</p>
							</td>
						</tr>
					</table>
					<?php submit_button( __( 'Veranstaltungen importieren', 'kurs-booking' ), 'primary', 'submit_events', false ); ?>
				</form>
			</div>

			<!-- Bookings Import -->
			<div class="card" style="max-width: 600px; margin-bottom: 20px;">
				<h3><?php esc_html_e( 'Buchungen importieren', 'kurs-booking' ); ?></h3>
				<p class="description">
					<?php esc_html_e( 'Laden Sie eine CSV-Datei mit MEC-Buchungen hoch. Veranstaltungen müssen zuerst importiert werden!', 'kurs-booking' ); ?>
				</p>
				<form method="post" enctype="multipart/form-data">
					<?php wp_nonce_field( 'kurs_booking_import', 'kurs_booking_import_nonce' ); ?>
					<input type="hidden" name="import_type" value="bookings">
					<table class="form-table">
						<tr>
							<th scope="row">
								<label for="bookings_file"><?php esc_html_e( 'CSV-Datei', 'kurs-booking' ); ?></label>
							</th>
							<td>
								<input type="file" name="bookings_file" id="bookings_file" accept=".csv">
								<p class="description">
									<?php esc_html_e( 'Exportieren Sie aus MEC: Buchungen → Export → CSV Format', 'kurs-booking' ); ?>
								</p>
							</td>
						</tr>
						<tr>
							<th scope="row">
								<label for="bookings_dry_run">
									<input type="checkbox" name="dry_run" id="bookings_dry_run" value="1">
									<?php esc_html_e( 'Testlauf (keine Daten speichern)', 'kurs-booking' ); ?>
								</label>
							</th>
							<td>
								<p class="description">
									<?php esc_html_e( 'Simuliert den Import ohne Änderungen vorzunehmen.', 'kurs-booking' ); ?>
								</p>
							</td>
						</tr>
					</table>
					<?php submit_button( __( 'Buchungen importieren', 'kurs-booking' ), 'primary', 'submit_bookings', false ); ?>
				</form>
			</div>

			<!-- Import Status -->
			<div class="card" style="max-width: 600px;">
				<h3><?php esc_html_e( 'Import-Status', 'kurs-booking' ); ?></h3>
				<?php
				$kurse_count    = wp_count_posts( 'kurs' );
				$buchungen_count = wp_count_posts( 'kurs-buchung' );
				?>
				<table class="widefat striped" style="max-width: 400px;">
					<tr>
						<td><strong><?php esc_html_e( 'Veranstaltungen (Kurs)', 'kurs-booking' ); ?></strong></td>
						<td><?php echo esc_html( $kurse_count->publish ?? 0 ); ?> <?php esc_html_e( 'veröffentlicht', 'kurs-booking' ); ?></td>
					</tr>
					<tr>
						<td><strong><?php esc_html_e( 'Buchungen', 'kurs-booking' ); ?></strong></td>
						<td><?php echo esc_html( $buchungen_count->publish ?? 0 ); ?> <?php esc_html_e( 'aktiv', 'kurs-booking' ); ?></td>
					</tr>
				</table>
			</div>
		</div>
		<?php
	}

	/**
	 * Handle MEC import
	 *
	 * @return array{success: bool, message: string, details: array<string>}
	 */
	private static function handle_import(): array {
        // phpcs:ignore WordPress.Security.NonceVerification.Missing -- Nonce verified in render_import_tab
		$import_type = isset( $_POST['import_type'] ) ? sanitize_key( $_POST['import_type'] ) : '';
        // phpcs:ignore WordPress.Security.NonceVerification.Missing
		$dry_run     = isset( $_POST['dry_run'] ) && '1' === $_POST['dry_run'];

		if ( 'events' === $import_type ) {
			return self::import_events_from_json( $dry_run );
		} elseif ( 'bookings' === $import_type ) {
			return self::import_bookings_from_csv( $dry_run );
		}

		return array(
			'success' => false,
			'message' => __( 'Ungültiger Import-Typ.', 'kurs-booking' ),
			'details' => array(),
		);
	}

	/**
	 * Import events from JSON file
	 *
	 * @param bool $dry_run Whether to simulate without saving.
	 * @return array{success: bool, message: string, details: array<string>}
	 */
	private static function import_events_from_json( bool $dry_run ): array {
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.NonceVerification.Missing -- Array indices checked below. Nonce verified in handle_import_request().
		if ( ! isset( $_FILES['events_file']['error'] ) || UPLOAD_ERR_OK !== $_FILES['events_file']['error'] ) {
			return array(
				'success' => false,
				'message' => __( 'Keine Datei hochgeladen oder Fehler beim Upload.', 'kurs-booking' ),
				'details' => array(),
			);
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.WP.AlternativeFunctions.file_get_contents_file_get_contents,WordPress.Security.NonceVerification.Missing -- $_FILES tmp_name validated above, sanitized by file_get_contents reading only. Nonce verified in handle_import_request().
		$file_content = file_get_contents( $_FILES['events_file']['tmp_name'] );
		if ( false === $file_content ) {
			return array(
				'success' => false,
				'message' => __( 'Datei konnte nicht gelesen werden.', 'kurs-booking' ),
				'details' => array(),
			);
		}

		$events = json_decode( $file_content, true );
		if ( json_last_error() !== JSON_ERROR_NONE || ! is_array( $events ) ) {
			return array(
				'success' => false,
				'message' => __( 'Ungültiges JSON-Format.', 'kurs-booking' ),
				'details' => array( json_last_error_msg() ),
			);
		}

		$imported = 0;
		$skipped  = 0;
		$details  = array();

		foreach ( $events as $event ) {
			$mec_id = $event['ID'] ?? 0;
			$title  = $event['title'] ?? '';

			if ( empty( $mec_id ) || empty( $title ) ) {
				$skipped++;
				continue;
			}

			// Check if already imported.
			$existing = get_posts(
				array(
					'post_type'   => 'kurs',
					'meta_key'    => '_mec_original_id',
					'meta_value'  => $mec_id,
					'numberposts' => 1,
				)
			);

			if ( ! empty( $existing ) ) {
				$skipped++;
				continue;
			}

			if ( ! $dry_run ) {
				$kurs_id = self::create_kurs_from_mec_event( $event );
				if ( $kurs_id ) {
					$imported++;
				} else {
					$skipped++;
				}
			} else {
				$imported++;
			}
		}

		$mode_text = $dry_run ? __( '(Testlauf)', 'kurs-booking' ) : '';
		return array(
			'success' => true,
			'message' => sprintf(
				/* translators: 1: imported count, 2: skipped count, 3: mode text */
				__( 'Events: %1$d importiert, %2$d übersprungen %3$s', 'kurs-booking' ),
				$imported,
				$skipped,
				$mode_text
			),
			'details' => $details,
		);
	}

	/**
	 * Create Kurs post from MEC event data
	 *
	 * @param array<string, mixed> $event MEC event data.
	 * @return int|false Post ID or false on failure.
	 */
	private static function create_kurs_from_mec_event( array $event ): int|false {
		$meta = $event['meta'] ?? array();
		$time = $event['time'] ?? array();
		$locations = $event['locations'] ?? array();

		// Get location string.
		$location_str = '';
		if ( ! empty( $locations ) ) {
			$first_loc = reset( $locations );
			$location_str = $first_loc['name'] ?? '';
			if ( ! empty( $first_loc['address'] ) ) {
				$location_str .= ', ' . $first_loc['address'];
			}
		}

		// Create post.
		$post_id = wp_insert_post(
			array(
				'post_title'   => wp_strip_all_tags( html_entity_decode( $event['title'] ?? '' ) ),
				'post_content' => wp_kses_post( $event['content'] ?? '' ),
				'post_status'  => 'publish',
				'post_type'    => 'kurs',
			)
		);

		if ( is_wp_error( $post_id ) || ! $post_id ) {
			return false;
		}

		// Store original MEC ID.
		update_post_meta( $post_id, '_mec_original_id', absint( $event['ID'] ?? 0 ) );

		// Date and time.
		update_post_meta( $post_id, '_kurs_start_date', sanitize_text_field( $meta['mec_start_date'] ?? '' ) );
		update_post_meta( $post_id, '_kurs_end_date', sanitize_text_field( $meta['mec_end_date'] ?? '' ) );
		update_post_meta( $post_id, '_kurs_start_time', sanitize_text_field( $time['start_raw'] ?? '' ) );
		update_post_meta( $post_id, '_kurs_end_time', sanitize_text_field( $time['end_raw'] ?? '' ) );

		// Location.
		update_post_meta( $post_id, '_kurs_location', sanitize_text_field( $location_str ) );

		// Tickets/Varianten.
		$varianten = array();
		$mec_tickets = $meta['mec_tickets'] ?? array();
		$var_id = 1;
		foreach ( $mec_tickets as $ticket ) {
			$varianten[] = array(
				'id'    => $var_id++,
				'name'  => sanitize_text_field( $ticket['name'] ?? '' ),
				'preis' => floatval( $ticket['price'] ?? 0 ),
				'limit' => absint( $ticket['limit'] ?? 0 ),
			);
		}
		if ( ! empty( $varianten ) ) {
			update_post_meta( $post_id, '_kurs_varianten', wp_json_encode( $varianten ) );
		}

		// Max participants.
		$bookings_limit = $meta['mec_booking']['bookings_limit'] ?? 0;
		update_post_meta( $post_id, '_kurs_max_participants', absint( $bookings_limit ) );

		// Default values.
		update_post_meta( $post_id, '_kurs_booking_enabled', '1' );
		update_post_meta( $post_id, '_kurs_produktart', 'kurs' );
		update_post_meta( $post_id, '_kurs_type', 'vor_ort' );

		return $post_id;
	}

	/**
	 * Import bookings from CSV file
	 *
	 * @param bool $dry_run Whether to simulate without saving.
	 * @return array{success: bool, message: string, details: array<string>}
	 */
	private static function import_bookings_from_csv( bool $dry_run ): array {
		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.NonceVerification.Missing -- Array indices checked below. Nonce verified in handle_import_request().
		if ( ! isset( $_FILES['bookings_file']['error'] ) || UPLOAD_ERR_OK !== $_FILES['bookings_file']['error'] ) {
			return array(
				'success' => false,
				'message' => __( 'Keine Datei hochgeladen oder Fehler beim Upload.', 'kurs-booking' ),
				'details' => array(),
			);
		}

		// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotValidated,WordPress.Security.ValidatedSanitizedInput.InputNotSanitized,WordPress.Security.NonceVerification.Missing -- $_FILES tmp_name validated above, used as file path only. Nonce verified in handle_import_request().
		$file_path = $_FILES['bookings_file']['tmp_name'];
		$handle    = fopen( $file_path, 'r' ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fopen
		if ( false === $handle ) {
			return array(
				'success' => false,
				'message' => __( 'Datei konnte nicht geöffnet werden.', 'kurs-booking' ),
				'details' => array(),
			);
		}

		// Build title to kurs mapping.
		$title_to_kurs = self::get_title_to_kurs_mapping();

		// Read header.
		$header = fgetcsv( $handle, 0, "\t" );
		if ( false === $header ) {
			fclose( $handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose
			return array(
				'success' => false,
				'message' => __( 'CSV-Header konnte nicht gelesen werden.', 'kurs-booking' ),
				'details' => array(),
			);
		}

		// Find column indices.
		$col_map = array_flip( $header );

		$imported   = 0;
		$skipped    = 0;
		$no_mapping = 0;
		$details    = array();

		while ( ( $row = fgetcsv( $handle, 0, "\t" ) ) !== false ) {
			$data = array_combine( $header, $row );
			if ( false === $data ) {
				$skipped++;
				continue;
			}

			$mec_booking_id = $data['ID'] ?? '';
			$event_title    = $data['Veranstaltung'] ?? '';
			$name           = $data['Name'] ?? '';

			// Check for existing import.
			$existing = get_posts(
				array(
					'post_type'   => 'kurs-buchung',
					'meta_key'    => '_mec_original_booking_id',
					'meta_value'  => $mec_booking_id,
					'numberposts' => 1,
				)
			);
			if ( ! empty( $existing ) ) {
				$skipped++;
				continue;
			}

			// Find Kurs by title.
			$kurs_id = self::find_kurs_by_title( $event_title, $title_to_kurs );
			if ( ! $kurs_id ) {
				$no_mapping++;
				continue;
			}

			if ( ! $dry_run ) {
				$buchung_id = self::create_buchung_from_csv_row( $data, $kurs_id );
				if ( $buchung_id ) {
					$imported++;
				} else {
					$skipped++;
				}
			} else {
				$imported++;
			}
		}

		fclose( $handle ); // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fclose

		$mode_text = $dry_run ? __( '(Testlauf)', 'kurs-booking' ) : '';
		return array(
			'success' => true,
			'message' => sprintf(
				/* translators: 1: imported count, 2: skipped count, 3: no mapping count, 4: mode text */
				__( 'Buchungen: %1$d importiert, %2$d übersprungen, %3$d ohne Kurs-Zuordnung %4$s', 'kurs-booking' ),
				$imported,
				$skipped,
				$no_mapping,
				$mode_text
			),
			'details' => $details,
		);
	}

	/**
	 * Get title to Kurs ID mapping
	 *
	 * @return array<string, int>
	 */
	private static function get_title_to_kurs_mapping(): array {
		$kurse = get_posts(
			array(
				'post_type'   => 'kurs',
				'numberposts' => -1,
				'post_status' => 'publish',
			)
		);

		$mapping = array();
		foreach ( $kurse as $kurs ) {
			$title = html_entity_decode( $kurs->post_title );
			$mapping[ $title ] = $kurs->ID;

			// Also add with decoded entities for matching.
			$title_decoded = html_entity_decode( $title, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
			$mapping[ $title_decoded ] = $kurs->ID;
		}

		return $mapping;
	}

	/**
	 * Find Kurs by event title with fuzzy matching
	 *
	 * @param string             $event_title Event title from CSV.
	 * @param array<string, int> $mapping     Title to Kurs ID mapping.
	 * @return int|null Kurs ID or null if not found.
	 */
	private static function find_kurs_by_title( string $event_title, array $mapping ): ?int {
		// Skip unknown events.
		if ( 'Unbekannt' === $event_title || empty( $event_title ) ) {
			return null;
		}

		// Exact match.
		if ( isset( $mapping[ $event_title ] ) ) {
			return $mapping[ $event_title ];
		}

		// Try decoded version.
		$decoded = html_entity_decode( $event_title, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
		if ( isset( $mapping[ $decoded ] ) ) {
			return $mapping[ $decoded ];
		}

		// Partial match (first 30 chars).
		$prefix = mb_substr( $event_title, 0, 30 );
		foreach ( $mapping as $title => $id ) {
			if ( str_starts_with( $title, $prefix ) ) {
				return $id;
			}
		}

		return null;
	}

	/**
	 * Create Buchung post from CSV row
	 *
	 * @param array<string, string> $data CSV row data.
	 * @param int                   $kurs_id Associated Kurs ID.
	 * @return int|false Post ID or false on failure.
	 */
	private static function create_buchung_from_csv_row( array $data, int $kurs_id ): int|false {
		$name  = $data['Name'] ?? '';
		$email = $data['E-Mail'] ?? '';

		// Parse status.
		$confirmed   = strtolower( $data['Bestätigung'] ?? '' );
		$verified    = strtolower( $data['Verifizierung'] ?? '' );
		$status      = 'pending';
		if ( 'ja' === $confirmed && 'ja' === $verified ) {
			$status = 'confirmed';
		} elseif ( 'nein' === $confirmed ) {
			$status = 'cancelled';
		}

		// Parse price.
		$price_str = $data['Gesamtpreis'] ?? '0';
		$price_str = preg_replace( '/[^\d,.]/', '', $price_str );
		$price_str = str_replace( ',', '.', $price_str );
		$price     = floatval( $price_str );

		// Create post.
		$post_id = wp_insert_post(
			array(
				'post_title'  => sprintf( '%s - %s', $name, get_the_title( $kurs_id ) ),
				'post_status' => 'publish',
				'post_type'   => 'kurs-buchung',
			)
		);

		if ( is_wp_error( $post_id ) || ! $post_id ) {
			return false;
		}

		// Store MEC original ID.
		update_post_meta( $post_id, '_mec_original_booking_id', sanitize_text_field( $data['ID'] ?? '' ) );
		update_post_meta( $post_id, '_mec_transaction_id', sanitize_text_field( $data['Transaktions-ID'] ?? '' ) );

		// Booking data.
		update_post_meta( $post_id, '_buchung_kurs_id', $kurs_id );
		update_post_meta( $post_id, '_buchung_name', sanitize_text_field( $name ) );
		update_post_meta( $post_id, '_buchung_email', sanitize_email( $email ) );
		update_post_meta( $post_id, '_buchung_phone', sanitize_text_field( $data['Telefonnummer'] ?? '' ) );
		update_post_meta( $post_id, '_buchung_total_price', $price );
		update_post_meta( $post_id, '_buchung_status', $status );
		update_post_meta( $post_id, '_buchung_anzahl', 1 );
		update_post_meta( $post_id, '_buchung_variante_id', 1 );

		// Parse and store order time.
		$order_time = $data['Bestellzeit'] ?? '';
		if ( ! empty( $order_time ) ) {
			$timestamp = strtotime( $order_time );
			if ( false !== $timestamp ) {
				update_post_meta( $post_id, '_buchung_created_at', gmdate( 'Y-m-d H:i:s', $timestamp ) );
			}
		}

		// Store custom fields as JSON.
		$custom_fields = array();
		$standard_cols = array(
			'ID', 'Veranstaltung', 'Anfangsdatum & Uhrzeit', 'Enddatum & Schlusszeit',
			'Standort', 'Bestellzeit', 'Kurs', 'Transaktions-ID', 'Gesamtpreis',
			'Schnittstelle', 'Name', 'E-Mail', 'Variante des Tickets', 'Bestätigung',
			'Verifizierung', 'Andere Termine', 'Checkin Status', 'Checkin DateTime',
			'Bestätigungsnummer', 'Telefonnummer',
		);
		foreach ( $data as $key => $value ) {
			if ( ! in_array( $key, $standard_cols, true ) && ! empty( $value ) ) {
				$custom_fields[ $key ] = $value;
			}
		}
		if ( ! empty( $custom_fields ) ) {
			update_post_meta( $post_id, '_buchung_custom_fields', wp_json_encode( $custom_fields ) );
		}

		return $post_id;
	}

	/**
	 * Render dienstleistungen (service types) settings tab
	 *
	 * Sprint 8.2: CRUD UI for managing Produktarten.
	 */
	private static function render_dienstleistungen_tab(): void {
		$dienstleistungen = Kurs_Booking_Dienstleistungen::get_all( true );
		$dashicons        = self::get_available_dashicons();
		?>
		<h2><?php esc_html_e( 'Dienstleistungen / Produktarten', 'kurs-booking' ); ?></h2>
		<p class="description">
			<?php esc_html_e( 'Definieren Sie hier die verfuegbaren Produktarten fuer Ihre Kurse. System-Eintraege (A-F) koennen nicht geloescht werden.', 'kurs-booking' ); ?>
		</p>

		<div id="kb-dienstleistungen-editor">
			<table class="kb-dienstleistungen-table widefat striped">
				<thead>
					<tr>
						<th class="kb-col-order" style="width: 50px;"><?php esc_html_e( 'Pos', 'kurs-booking' ); ?></th>
						<th class="kb-col-label" style="width: 60px;"><?php esc_html_e( 'Prefix', 'kurs-booking' ); ?></th>
						<th class="kb-col-name"><?php esc_html_e( 'Name', 'kurs-booking' ); ?></th>
						<th class="kb-col-buchung" style="width: 100px;"><?php esc_html_e( 'Buchung', 'kurs-booking' ); ?></th>
						<th class="kb-col-termin" style="width: 110px;"><?php esc_html_e( 'Termin', 'kurs-booking' ); ?></th>
						<th class="kb-col-badge" style="width: 180px;"><?php esc_html_e( 'Badge', 'kurs-booking' ); ?></th>
						<th class="kb-col-active" style="width: 60px;"><?php esc_html_e( 'Aktiv', 'kurs-booking' ); ?></th>
						<th class="kb-col-actions" style="width: 60px;"><?php esc_html_e( 'Aktion', 'kurs-booking' ); ?></th>
					</tr>
				</thead>
				<tbody id="kb-dienstleistungen-list">
					<?php
					$index = 0;
					foreach ( $dienstleistungen as $dl ) :
						self::render_dienstleistung_row( $dl, $index, $dashicons );
						++$index;
					endforeach;
					?>
				</tbody>
			</table>

			<p style="margin-top: 16px;">
				<button type="button" class="button kb-add-dienstleistung" id="kb-add-dienstleistung">
					<span class="dashicons dashicons-plus-alt2" style="margin-top: 3px;"></span>
					<?php esc_html_e( 'Dienstleistung hinzufuegen', 'kurs-booking' ); ?>
				</button>
			</p>
		</div>

		<!-- Template for new row (used by JavaScript) -->
		<script type="text/html" id="kb-dienstleistung-row-template">
			<?php self::render_dienstleistung_row( self::get_empty_dienstleistung(), '__INDEX__', $dashicons ); ?>
		</script>
		<?php
	}

	/**
	 * Render a single dienstleistung row
	 *
	 * @param array        $dl        Dienstleistung data.
	 * @param int|string   $index     Row index.
	 * @param array        $dashicons Available dashicons.
	 */
	private static function render_dienstleistung_row( array $dl, int|string $index, array $dashicons ): void {
		$prefix    = "kurs_booking_dienstleistungen[{$index}]";
		$is_system = ! empty( $dl['system'] );
		?>
		<tr class="kb-dienstleistung-row" data-index="<?php echo esc_attr( (string) $index ); ?>">
			<td class="kb-col-order">
				<span class="dashicons dashicons-move kb-drag-handle" style="cursor: move; color: #999;"></span>
				<input type="hidden" name="<?php echo esc_attr( $prefix ); ?>[order]"
					   value="<?php echo esc_attr( (string) ( $dl['order'] ?? $index ) ); ?>">
				<input type="hidden" name="<?php echo esc_attr( $prefix ); ?>[id]"
					   value="<?php echo esc_attr( $dl['id'] ?? '' ); ?>">
				<input type="hidden" name="<?php echo esc_attr( $prefix ); ?>[system]"
					   value="<?php echo $is_system ? '1' : '0'; ?>">
			</td>
			<td class="kb-col-label">
				<input type="text" name="<?php echo esc_attr( $prefix ); ?>[label]"
					   value="<?php echo esc_attr( $dl['label'] ?? '' ); ?>"
					   placeholder="A)" class="small-text" style="width: 50px;">
			</td>
			<td class="kb-col-name">
				<input type="text" name="<?php echo esc_attr( $prefix ); ?>[name]"
					   value="<?php echo esc_attr( $dl['name'] ?? '' ); ?>"
					   placeholder="<?php esc_attr_e( 'Name eingeben', 'kurs-booking' ); ?>"
					   required style="width: 100%;">
			</td>
			<td class="kb-col-buchung">
				<select name="<?php echo esc_attr( $prefix ); ?>[buchungsart]" style="width: 100%;">
					<option value="direkt" <?php selected( $dl['buchungsart'] ?? 'direkt', 'direkt' ); ?>>
						<?php esc_html_e( 'Direkt', 'kurs-booking' ); ?>
					</option>
					<option value="anfrage" <?php selected( $dl['buchungsart'] ?? '', 'anfrage' ); ?>>
						<?php esc_html_e( 'Anfrage', 'kurs-booking' ); ?>
					</option>
				</select>
			</td>
			<td class="kb-col-termin">
				<select name="<?php echo esc_attr( $prefix ); ?>[terminart]" style="width: 100%;">
					<option value="fix" <?php selected( $dl['terminart'] ?? 'fix', 'fix' ); ?>>
						<?php esc_html_e( 'Fix', 'kurs-booking' ); ?>
					</option>
					<option value="individuell" <?php selected( $dl['terminart'] ?? '', 'individuell' ); ?>>
						<?php esc_html_e( 'Individuell', 'kurs-booking' ); ?>
					</option>
					<option value="unbegrenzt" <?php selected( $dl['terminart'] ?? '', 'unbegrenzt' ); ?>>
						<?php esc_html_e( 'Unbegrenzt', 'kurs-booking' ); ?>
					</option>
				</select>
			</td>
			<td class="kb-col-badge" style="display: flex; gap: 8px; align-items: center;">
				<input type="color" name="<?php echo esc_attr( $prefix ); ?>[badge_color]"
					   value="<?php echo esc_attr( $dl['badge_color'] ?? '#4CAF50' ); ?>"
					   style="width: 40px; height: 30px; padding: 0; border: 1px solid #ddd;">
				<select name="<?php echo esc_attr( $prefix ); ?>[badge_icon]" class="kb-icon-select" style="flex: 1;">
					<?php foreach ( $dashicons as $icon => $label ) : ?>
						<option value="<?php echo esc_attr( $icon ); ?>"
								<?php selected( $dl['badge_icon'] ?? 'calendar-alt', $icon ); ?>>
							<?php echo esc_html( $label ); ?>
						</option>
					<?php endforeach; ?>
				</select>
			</td>
			<td class="kb-col-active" style="text-align: center;">
				<input type="checkbox" name="<?php echo esc_attr( $prefix ); ?>[active]" value="1"
					   <?php checked( $dl['active'] ?? true ); ?>>
			</td>
			<td class="kb-col-actions" style="text-align: center;">
				<?php if ( ! $is_system ) : ?>
					<button type="button" class="button-link kb-delete-dienstleistung"
							title="<?php esc_attr_e( 'Loeschen', 'kurs-booking' ); ?>"
							style="color: #b32d2e;">
						<span class="dashicons dashicons-trash"></span>
					</button>
				<?php else : ?>
					<span class="dashicons dashicons-lock" title="<?php esc_attr_e( 'System-Eintrag', 'kurs-booking' ); ?>"
						  style="color: #999;"></span>
				<?php endif; ?>
			</td>
		</tr>
		<?php
	}

	/**
	 * Get empty dienstleistung template
	 *
	 * @return array Empty dienstleistung data.
	 */
	private static function get_empty_dienstleistung(): array {
		return array(
			'id'          => '',
			'name'        => '',
			'label'       => '',
			'buchungsart' => 'direkt',
			'terminart'   => 'fix',
			'badge_color' => '#4CAF50',
			'badge_icon'  => 'calendar-alt',
			'order'       => 99,
			'active'      => true,
			'system'      => false,
		);
	}

	/**
	 * Get available dashicons for badge selection
	 *
	 * @return array<string, string> Icon name => Label pairs.
	 */
	private static function get_available_dashicons(): array {
		return array(
			'calendar-alt'   => __( 'Kalender', 'kurs-booking' ),
			'groups'         => __( 'Gruppe', 'kurs-booking' ),
			'video-alt3'     => __( 'Video', 'kurs-booking' ),
			'heart'          => __( 'Herz', 'kurs-booking' ),
			'admin-users'    => __( 'Person', 'kurs-booking' ),
			'format-video'   => __( 'Film', 'kurs-booking' ),
			'playlist-video' => __( 'Playlist', 'kurs-booking' ),
			'location-alt'   => __( 'Ort', 'kurs-booking' ),
			'laptop'         => __( 'Laptop', 'kurs-booking' ),
			'desktop'        => __( 'Desktop', 'kurs-booking' ),
			'smartphone'     => __( 'Smartphone', 'kurs-booking' ),
			'welcome-learn-more' => __( 'Lernen', 'kurs-booking' ),
			'book'           => __( 'Buch', 'kurs-booking' ),
			'edit'           => __( 'Stift', 'kurs-booking' ),
			'star-filled'    => __( 'Stern', 'kurs-booking' ),
			'awards'         => __( 'Auszeichnung', 'kurs-booking' ),
			'megaphone'      => __( 'Megafon', 'kurs-booking' ),
			'lightbulb'      => __( 'Gluehbirne', 'kurs-booking' ),
			'businessman'    => __( 'Business', 'kurs-booking' ),
			'universal-access' => __( 'Universal', 'kurs-booking' ),
		);
	}
}
