<?php

class Trainingssystem_Plugin_Module_Calendar {

	public function getCalendarTrainingsAjax(){
		if (!current_user_can('edit_posts')) { wp_send_json_error('forbidden', 403); }

		$args = array(
			'post_type' => 'trainings',
			'post_status' => 'publish',
			'posts_per_page' => -1,
			'orderby' => 'title',
			'order' => 'ASC',
			'meta_query' => array(
				array(
					'key' => 'calendarTraining',
					'value' => '1',
					'compare' => '='
				)
			)
		);

		$q = new WP_Query($args);
		$result = array();
		if ($q->have_posts()){
            global $wpdb;
            $table_name_lektion = $wpdb->prefix . TRAININGSSYSTEM_PLUGIN_DB_TRAINING_LEKTIONEN;
			while($q->have_posts()){
				$q->the_post();
				$trainingId = get_the_ID();
				$trainingTitle = get_the_title();
				$trainingSlug = get_post_field('post_name', $trainingId);

				$lessons = array();
				$lektionRows = $wpdb->get_results($wpdb->prepare(
					"SELECT l.lektion_id as id FROM $table_name_lektion l WHERE l.training_id = %d ORDER BY l.lektion_index ASC",
					$trainingId
				));
				if ($lektionRows){
					foreach($lektionRows as $lr){
						$lessonId = intval($lr->id);
						$lessonTitle = get_the_title($lessonId);
						$lessonSlug = get_post_field('post_name', $lessonId);

						$seiten = Trainingssystem_Plugin_Database::getInstance()->TrainingseitenDao->getLektionenSeiten($trainingId, $lessonId);
						$firstPageSlug = '';
						if (is_array($seiten) && count($seiten) > 0){
							$firstPageId = $seiten[0]->getId();
							$firstPageSlug = get_post_field('post_name', $firstPageId);
						}

						$lessons[] = array(
							'id' => $lessonId,
							'title' => $lessonTitle,
							'slug' => $lessonSlug,
							'first_page_slug' => $firstPageSlug,
						);
					}
				}

				$result[] = array(
					'id' => $trainingId,
					'title' => $trainingTitle,
					'slug' => $trainingSlug,
					'lessons' => $lessons,
				);
			}
			wp_reset_postdata();
		}

		wp_send_json($result);
	}

	/**
	 * AJAX: Liefert entry_date-Liste für einen Monat (nur eingeloggte Nutzer)
	 */
	public function getMonthEntriesAjax(){
		$uid = get_current_user_id();
		if ($uid <= 0) { wp_send_json_error('forbidden', 403); }
		
		// User-Modus prüfen: Falls ein anderer User ausgewählt ist, dessen Einträge laden
		$selectui = get_user_meta($uid, 'coach_select_user', true);
		if ($selectui != '') {
			$uid = $selectui;
		}
		
		$calendarId = isset($_POST['calendar_id']) ? intval($_POST['calendar_id']) : (isset($_GET['calendar_id']) ? intval($_GET['calendar_id']) : 0);
		$year = isset($_POST['year']) ? intval($_POST['year']) : (isset($_GET['year']) ? intval($_GET['year']) : 0);
		$month = isset($_POST['month']) ? intval($_POST['month']) : (isset($_GET['month']) ? intval($_GET['month']) : 0);
		if ($calendarId <= 0 || $year <= 0 || $month <= 0 || $month > 12) { wp_send_json_error('invalid_params', 400); }
		$entries = Trainingssystem_Plugin_Database::getInstance()->CalendarEntry->getEntriesByMonth($calendarId, $year, $month, $uid);
		$dates = array();
		foreach ($entries as $e) { $dates[] = $e->getEntryDate(); }
		wp_send_json(array('calendar_id' => $calendarId, 'year' => $year, 'month' => $month, 'dates' => array_values(array_unique($dates))));
	}

    public function add_calendar_meta_box() {
        // Optionen-Box nur anzeigen, wenn bereits veröffentlicht
        if (isset($_GET['post']) && is_numeric($_GET['post'])) {
            $post = get_post(intval($_GET['post']));
            if ($post && $post->post_status === 'publish') {
                add_meta_box(
                    'ts-calendar-options-meta-box',
                    'Kalender-Optionen',
                    array($this, 'render_calendar_options_meta_box'),
                    'kalender',
                    'normal',
                    'high',
                    null
                );
                return;
            }
        }

        // Hinweisbox, solange noch nicht veröffentlicht
        add_meta_box(
            'ts-calendar-titlefirst-meta-box',
            'Bitte Titel vergeben',
            array($this, 'render_calendar_titlefirst_meta_box'),
            'kalender',
            'normal',
            'high',
            null
        );
    }

    public function render_calendar_titlefirst_meta_box() {
		$twig = Trainingssystem_Plugin_Twig::getInstance()->twig;
		echo $twig->render('forms/backend-form-titlefirst.html', []);
    }

    public function render_calendar_options_meta_box() {
        global $post;
        $postid = $post->ID;

        $opts_json = get_post_meta($postid, 'calendar_options', true);
        $opts = array();
        if (is_string($opts_json) && trim($opts_json) !== '') {
            $decoded = json_decode($opts_json, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                $opts = $decoded;
            }
        }

        $calendar_color = isset($opts['calendar_color']) ? $opts['calendar_color'] : '#3a86ff';
        $button_label   = isset($opts['calendar_button_label']) && trim($opts['calendar_button_label']) !== '' ? $opts['calendar_button_label'] : (isset($opts['button_title']) && trim($opts['button_title']) !== '' ? $opts['button_title'] : '');
        $target_url     = isset($opts['target_url']) ? $opts['target_url'] : (isset($opts['button_link']) ? $opts['button_link'] : '');
        $lektionen_button_label = isset($opts['lektionen_button_label']) ? $opts['lektionen_button_label'] : '';
        $lektionen_button_url = isset($opts['lektionen_button_url']) ? $opts['lektionen_button_url'] : '';
        $abschliessen_button_label = isset($opts['abschliessen_button_label']) ? $opts['abschliessen_button_label'] : '';
        $abschliessen_button_url = isset($opts['abschliessen_button_url']) ? $opts['abschliessen_button_url'] : '';
        $zum_kalender_button_label = isset($opts['zum_kalender_button_label']) ? $opts['zum_kalender_button_label'] : '';
        $zum_kalender_button_url = isset($opts['zum_kalender_button_url']) ? $opts['zum_kalender_button_url'] : '';
        $button_css = isset($opts['calendar_button_css']) ? $opts['calendar_button_css'] : '';
        $button_parent_css = isset($opts['calendar_button_parent_css']) ? $opts['calendar_button_parent_css'] : '';
        $button_classes = isset($opts['calendar_button_classes']) ? $opts['calendar_button_classes'] : '';
        $calendar_widget_css = isset($opts['calendar_widget_css']) ? $opts['calendar_widget_css'] : '';
        $calendar_widget_classes = isset($opts['calendar_widget_classes']) ? $opts['calendar_widget_classes'] : '';
        $calendar_status_dot_css = isset($opts['calendar_status_dot_css']) ? $opts['calendar_status_dot_css'] : '';
        $calendar_hover_bg_css = isset($opts['calendar_hover_bg_css']) ? $opts['calendar_hover_bg_css'] : '';
        $calendar_selected_day_css = isset($opts['calendar_selected_day_css']) ? $opts['calendar_selected_day_css'] : '';
        $calendar_input_css = isset($opts['calendar_input_css']) ? $opts['calendar_input_css'] : '';
        $calendar_weekdays_css = isset($opts['calendar_weekdays_css']) ? $opts['calendar_weekdays_css'] : '';
        $calendar_status_dot_color = isset($opts['calendar_status_dot_color']) && trim($opts['calendar_status_dot_color']) !== '' ? $opts['calendar_status_dot_color'] : '#28a745';
        $calendar_hover_bg_color = isset($opts['calendar_hover_bg_color']) ? $opts['calendar_hover_bg_color'] : '';
        $left_button_label = isset($opts['left_button_label']) ? $opts['left_button_label'] : '';
        $left_button_url = isset($opts['left_button_url']) ? $opts['left_button_url'] : '';
        $left_button_css = isset($opts['left_button_css']) ? $opts['left_button_css'] : '';
        $left_button_parent_css = isset($opts['left_button_parent_css']) ? $opts['left_button_parent_css'] : '';
        $left_button_classes = isset($opts['left_button_classes']) ? $opts['left_button_classes'] : '';

        $shortcode = "[ts_calendar id='" . $postid . "']";

        // Basis-URL für Subdomain-Support
        $base_url = home_url();

        $twig = Trainingssystem_Plugin_Twig::getInstance()->twig;
        echo $twig->render('calendar/admin-backend-calendar-options.html', [
            'postid' => $postid,
            'shortcode' => $shortcode,
            'dataexport_url' => get_permalink(get_option(TRAININGSSYSTEM_PLUGIN_SETTINGS)['dataexport']),
            'base_url' => $base_url,
            'calendar_color' => $calendar_color,
            'button_label' => $button_label,
            'target_url' => $target_url,
            'button_css' => $button_css,
            'button_parent_css' => $button_parent_css,
            'button_classes' => $button_classes,
            'calendar_widget_css' => $calendar_widget_css,
            'calendar_widget_classes' => $calendar_widget_classes,
            'calendar_status_dot_css' => $calendar_status_dot_css,
            'calendar_hover_bg_css' => $calendar_hover_bg_css,
            'calendar_selected_day_css' => $calendar_selected_day_css,
            'calendar_input_css' => $calendar_input_css,
            'calendar_weekdays_css' => $calendar_weekdays_css,
            'left_button_label' => $left_button_label,
            'left_button_url' => $left_button_url,
            'left_button_css' => $left_button_css,
            'left_button_parent_css' => $left_button_parent_css,
            'left_button_classes' => $left_button_classes,
            'lektionen_button_label' => $lektionen_button_label,
            'lektionen_button_url' => $lektionen_button_url,
            'abschliessen_button_label' => $abschliessen_button_label,
            'abschliessen_button_url' => $abschliessen_button_url,
            'zum_kalender_button_label' => $zum_kalender_button_label,
            'zum_kalender_button_url' => $zum_kalender_button_url,
        ]);
    }

    public function saveCalendarOptions() {
        if (!current_user_can('edit_posts')) { wp_die(); }
        if (!isset($_POST['postid']) || !is_numeric($_POST['postid'])) { wp_die(); }

        $postid = intval($_POST['postid']);
        $options_json = isset($_POST['options']) ? wp_unslash($_POST['options']) : '';

        $decoded = json_decode($options_json, true);
        if (json_last_error() !== JSON_ERROR_NONE || !is_array($decoded)) { echo 'invalid'; wp_die(); }

        $save = array(
            'calendar_color' => isset($decoded['calendar_color']) ? sanitize_hex_color($decoded['calendar_color']) : '',
            'calendar_button_label' => (function() use ($decoded){
                $val = isset($decoded['calendar_button_label'])
                    ? wp_strip_all_tags($decoded['calendar_button_label'])
                    : (isset($decoded['button_title']) ? wp_strip_all_tags($decoded['button_title']) : '');
                return $val;
            })(),
            'target_url' => isset($decoded['target_url'])
                ? esc_url_raw($decoded['target_url'])
                : (isset($decoded['button_link']) ? esc_url_raw($decoded['button_link']) : ''),
            'lektionen_button_label' => isset($decoded['lektionen_button_label']) ? wp_strip_all_tags($decoded['lektionen_button_label']) : '',
            'lektionen_button_url' => isset($decoded['lektionen_button_url']) ? esc_url_raw($decoded['lektionen_button_url']) : '',
            'abschliessen_button_label' => isset($decoded['abschliessen_button_label']) ? wp_strip_all_tags($decoded['abschliessen_button_label']) : '',
            'abschliessen_button_url' => isset($decoded['abschliessen_button_url']) ? esc_url_raw($decoded['abschliessen_button_url']) : '',
            'zum_kalender_button_label' => isset($decoded['zum_kalender_button_label']) ? wp_strip_all_tags($decoded['zum_kalender_button_label']) : '',
            'zum_kalender_button_url' => isset($decoded['zum_kalender_button_url']) ? esc_url_raw($decoded['zum_kalender_button_url']) : '',
            'calendar_button_css' => isset($decoded['calendar_button_css']) ? sanitize_text_field($decoded['calendar_button_css']) : '',
            'calendar_button_parent_css' => isset($decoded['calendar_button_parent_css']) ? sanitize_text_field($decoded['calendar_button_parent_css']) : '',
            'calendar_button_classes' => isset($decoded['calendar_button_classes']) ? sanitize_text_field($decoded['calendar_button_classes']) : '',
            'calendar_widget_css' => isset($decoded['calendar_widget_css']) ? sanitize_text_field($decoded['calendar_widget_css']) : '',
            'calendar_widget_classes' => isset($decoded['calendar_widget_classes']) ? sanitize_text_field($decoded['calendar_widget_classes']) : '',
            'calendar_status_dot_css' => isset($decoded['calendar_status_dot_css']) ? sanitize_text_field($decoded['calendar_status_dot_css']) : '',
            'calendar_hover_bg_css' => isset($decoded['calendar_hover_bg_css']) ? sanitize_text_field($decoded['calendar_hover_bg_css']) : '',
            'calendar_selected_day_css' => isset($decoded['calendar_selected_day_css']) ? sanitize_text_field($decoded['calendar_selected_day_css']) : '',
            'calendar_input_css' => isset($decoded['calendar_input_css']) ? sanitize_text_field($decoded['calendar_input_css']) : '',
            'calendar_weekdays_css' => isset($decoded['calendar_weekdays_css']) ? sanitize_text_field($decoded['calendar_weekdays_css']) : '',
            'left_button_label' => isset($decoded['left_button_label']) ? wp_strip_all_tags($decoded['left_button_label']) : '',
            'left_button_url' => isset($decoded['left_button_url']) ? esc_url_raw($decoded['left_button_url']) : '',
            'left_button_css' => isset($decoded['left_button_css']) ? sanitize_text_field($decoded['left_button_css']) : '',
            'left_button_parent_css' => isset($decoded['left_button_parent_css']) ? sanitize_text_field($decoded['left_button_parent_css']) : '',
            'left_button_classes' => isset($decoded['left_button_classes']) ? sanitize_text_field($decoded['left_button_classes']) : '',
        );
        $json = wp_json_encode($save, JSON_UNESCAPED_UNICODE);

        // Bestehende Einträge ermitteln
        $existingValues = get_post_meta($postid, 'calendar_options', false); // alle Werte
        if (empty($existingValues)) {
            // Noch kein Eintrag vorhanden -> einmalig anlegen (unique)
            add_post_meta($postid, 'calendar_options', $json, true);
        } else {
            // Doppelte Werte bereinigen (nur den ersten behalten)
            // Hinweis: $existingValues ist eine Liste der Werte, nicht der IDs
            for ($i = 1; $i < count($existingValues); $i++) {
                delete_post_meta($postid, 'calendar_options', $existingValues[$i]);
            }
            // Den verbliebenen Wert aktualisieren, damit die meta_id stabil bleibt
            $prev = $existingValues[0];
            update_post_meta($postid, 'calendar_options', $json, $prev);
        }
        echo 'ok';
        wp_die();
    }

    /**
     * Wird vor dem endgültigen Löschen eines Beitrags aufgerufen.
     * Löscht bei Post-Type 'kalender' die zugehörigen Calendar-Entries
     * sowie die referenzierten Form-Daten (nur die zwei genannten Tabellen).
     */
    public function handle_before_delete_post($post_id){
        if (!is_numeric($post_id)) { return; }
        $post_type = get_post_type($post_id);
        if ($post_type !== 'kalender') { return; }

        // Nur endgültiges Löschen erreicht diesen Hook; bei Papierkorb passiert nichts.
        $db = Trainingssystem_Plugin_Database::getInstance();
        if (isset($db->CalendarEntry) && method_exists($db->CalendarEntry, 'deleteEntriesByCalendar')) {
            $db->CalendarEntry->deleteEntriesByCalendar(intval($post_id));
        }

        // Postmeta bereinigen
        delete_post_meta($post_id, 'calendar_options');
    }

    /**
     * AJAX: Löscht alle Formulardaten (wp_md_trainingsmgr_ts_forms_data) und Kalender-Einträge (wp_md_trainingsmgr_calendar_entries)
     * für einen spezifischen Kalender.
     */
    public function deleteCalendarData() {
        if (!current_user_can('edit_posts')) { wp_send_json_error('forbidden', 403); }
        $calendarId = isset($_POST['calendar_id']) ? intval($_POST['calendar_id']) : 0;
        if ($calendarId <= 0) { wp_send_json_error('invalid_params', 400); }

        global $wpdb;
        $calendar_entries_table = $wpdb->prefix . Trainingssystem_Plugin_Database_Calendar_Entry_Daoimple::$dbprefix; // wp_md_trainingsmgr_calendar_entries
        $formdata_table = $wpdb->prefix . Trainingssystem_Plugin_Database_Formdata_Daoimple::$dbprefix; // wp_md_trainingsmgr_ts_forms_data

        // Sammle eindeutige form_data_id für diesen Kalender
        $formDataIds = $wpdb->get_col($wpdb->prepare(
            "SELECT DISTINCT form_data_id FROM {$calendar_entries_table} WHERE calendar_id = %d AND form_data_id IS NOT NULL",
            $calendarId
        ));

        $deletedFormData = 0;
        $deletedCalendarEntries = 0;

        // Lösche die referenzierten Formulardaten
        if (!empty($formDataIds)) {
            $idsPlaceholders = implode(',', array_fill(0, count($formDataIds), '%d'));
            $sql = $wpdb->prepare("DELETE FROM {$formdata_table} WHERE ID IN ($idsPlaceholders)", $formDataIds);
            $result = $wpdb->query($sql);
            if ($result === false) {
                wp_send_json_error('db_error', 500);
            }
            $deletedFormData = intval($result);
        }

        // Lösche alle Kalender-Einträge für diesen Kalender
        $calendarEntriesResult = $wpdb->delete(
            $calendar_entries_table,
            array('calendar_id' => $calendarId),
            array('%d')
        );
        if ($calendarEntriesResult === false) {
            wp_send_json_error('db_error', 500);
        }
        $deletedCalendarEntries = intval($calendarEntriesResult);

        wp_send_json_success(array(
            'deleted_formdata' => $deletedFormData,
            'deleted_calendar_entries' => $deletedCalendarEntries,
            'total_deleted' => $deletedFormData + $deletedCalendarEntries
        ));
    }

    // Shortcode Renderer: [ts_calendar id='123']
    public function shortcodeCalendar($atts){
        $id = isset($atts['id']) ? intval($atts['id']) : 0;
        if ($id <= 0 || strtolower(get_post_type($id)) !== 'kalender') {
            return '';
        }

        $uid = uniqid('cal-');
        $opts_json = get_post_meta($id, 'calendar_options', true);
        $opts = array();
        if (is_string($opts_json) && trim($opts_json) !== '') {
            $decoded = json_decode($opts_json, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) { $opts = $decoded; }
        }
        $calendar_color = isset($opts['calendar_color']) ? $opts['calendar_color'] : '#3a86ff';
        $button_label = isset($opts['calendar_button_label']) && trim($opts['calendar_button_label']) !== '' ? $opts['calendar_button_label'] : (isset($opts['button_title']) && trim($opts['button_title']) !== '' ? $opts['button_title'] : '');
        $base_target_url = isset($opts['target_url']) ? $opts['target_url'] : (isset($opts['button_link']) ? $opts['button_link'] : '');
        
        // Kalender-Parameter zur target_url hinzufügen
        $target_url = $base_target_url;
        if (!empty($base_target_url)) {
            $url_parts = parse_url($base_target_url);
            $query_params = array();
            if (isset($url_parts['query'])) {
                parse_str($url_parts['query'], $query_params);
            }
            
            // Kalender-Parameter hinzufügen
            $query_params['calendar_id'] = $id;
            $query_params['date'] = '{{selected_date}}'; // Platzhalter für JavaScript
            
            // URL neu zusammenbauen - sicher mit allen Teilen
            $target_url = '';
            
            // Scheme und Host (nur wenn vorhanden)
            if (isset($url_parts['scheme']) && isset($url_parts['host'])) {
                $target_url .= $url_parts['scheme'] . '://' . $url_parts['host'];
                if (isset($url_parts['port'])) {
                    $target_url .= ':' . $url_parts['port'];
                }
            }
            
            // Path (immer vorhanden bei relativen URLs)
            if (isset($url_parts['path'])) {
                $target_url .= $url_parts['path'];
            }
            
            // Query-Parameter
            $target_url .= '?' . http_build_query($query_params);
            
            // Fragment
            if (isset($url_parts['fragment'])) {
                $target_url .= '#' . $url_parts['fragment'];
            }
        }
        $lektionen_button_label = isset($opts['lektionen_button_label']) ? $opts['lektionen_button_label'] : '';
        $lektionen_button_url = isset($opts['lektionen_button_url']) ? $opts['lektionen_button_url'] : '';
        $abschliessen_button_label = isset($opts['abschliessen_button_label']) ? $opts['abschliessen_button_label'] : '';
        $abschliessen_button_url = isset($opts['abschliessen_button_url']) ? $opts['abschliessen_button_url'] : '';
        $zum_kalender_button_label = isset($opts['zum_kalender_button_label']) ? $opts['zum_kalender_button_label'] : '';
        $zum_kalender_button_url = isset($opts['zum_kalender_button_url']) ? $opts['zum_kalender_button_url'] : '';
        $button_css = isset($opts['calendar_button_css']) ? $opts['calendar_button_css'] : '';
        $button_parent_css = isset($opts['calendar_button_parent_css']) ? $opts['calendar_button_parent_css'] : '';
        $button_classes = isset($opts['calendar_button_classes']) ? $opts['calendar_button_classes'] : '';
        $calendar_widget_css = isset($opts['calendar_widget_css']) ? $opts['calendar_widget_css'] : '';
        $calendar_widget_classes = isset($opts['calendar_widget_classes']) ? $opts['calendar_widget_classes'] : '';
        $calendar_status_dot_css = isset($opts['calendar_status_dot_css']) ? $opts['calendar_status_dot_css'] : '';
        $calendar_hover_bg_css = isset($opts['calendar_hover_bg_css']) ? $opts['calendar_hover_bg_css'] : '';
        $calendar_selected_day_css = isset($opts['calendar_selected_day_css']) ? $opts['calendar_selected_day_css'] : '';
        $calendar_input_css = isset($opts['calendar_input_css']) ? $opts['calendar_input_css'] : '';
        $calendar_weekdays_css = isset($opts['calendar_weekdays_css']) ? $opts['calendar_weekdays_css'] : '';
        $left_button_label = isset($opts['left_button_label']) ? $opts['left_button_label'] : '';
        $left_button_url = isset($opts['left_button_url']) ? $opts['left_button_url'] : '';
        $left_button_css = isset($opts['left_button_css']) ? $opts['left_button_css'] : '';
        $left_button_parent_css = isset($opts['left_button_parent_css']) ? $opts['left_button_parent_css'] : '';
        $left_button_classes = isset($opts['left_button_classes']) ? $opts['left_button_classes'] : '';

        // Einträge des aktuellen Monats (nur aktueller Nutzer) vorab laden
        $currentUserId = get_current_user_id();
        
        // User-Modus prüfen: Falls ein anderer User ausgewählt ist, dessen Einträge laden
        $selectui = get_user_meta($currentUserId, 'coach_select_user', true);
        if ($selectui != '') {
            $currentUserId = $selectui;
        }
        
        $initialYear = (int)date('Y', current_time('timestamp'));
        $initialMonth = (int)date('n', current_time('timestamp'));
        $initialDates = array();
        if ($currentUserId > 0) {
            $initialEntries = Trainingssystem_Plugin_Database::getInstance()->CalendarEntry->getEntriesByMonth($id, $initialYear, $initialMonth, $currentUserId);
            foreach ($initialEntries as $e) { $initialDates[] = $e->getEntryDate(); }
        }

        ob_start();
        ?>
        <style>
        :root{
          --fp-font-size: 16px;
          --fp-header-h: 52px;
          --fp-weekdays-h: 36px;
          --fp-day-size: 44px;
        }
        #calendarContainer-<?php echo esc_attr($uid);?> { padding: 0; }
        #fpCalendar-<?php echo esc_attr($uid);?> { width: 100%; display: flex; flex-direction: column; align-items: center; }
        .flatpickr-calendar.inline{
          width: 100%; max-width: none; box-shadow: none; border: 1px solid #dee2e6; border-radius: .5rem; font-size: var(--fp-font-size);
        }
        .flatpickr-months{ height: var(--fp-header-h); }
        .flatpickr-months .flatpickr-month{ height: var(--fp-header-h); display: flex; align-items: center; justify-content: center; padding: 0 .5rem; }
        .flatpickr-months .flatpickr-prev-month,
        .flatpickr-months .flatpickr-next-month{ height: var(--fp-header-h); width: var(--fp-header-h); display: flex; align-items: center; justify-content: center; }
        .flatpickr-months .flatpickr-prev-month svg,
        .flatpickr-months .flatpickr-next-month svg{ width: 1.1em; height: 1.1em; }
        .flatpickr-current-month{ display: flex; align-items: center; gap: .5rem; justify-content: center; }
        .flatpickr-weekdays{ height: var(--fp-weekdays-h); }
        .flatpickr-weekdays .flatpickr-weekday{ line-height: var(--fp-weekdays-h); }
        .flatpickr-days{ width: 100%; }
        .dayContainer{ width: 100%; min-width: 100%; max-width: 100%; }
        .flatpickr-day{ width: calc(100% / 7); height: var(--fp-day-size); line-height: var(--fp-day-size); max-width: none; box-sizing: border-box; border-radius: .375rem; }
        /* Punkt-Indikator für erledigte Tage (nur Punkt, grün) */
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-day.ts-has-entry{ position: relative; }
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-day.ts-has-entry::after{
          content: '';
          position: absolute;
          bottom: 6px;
          left: 50%;
          transform: translateX(-50%);
          width: 6px; height: 6px;
          background: #28a745;
          border-radius: 50%;
        }
        <?php if (!empty($calendar_status_dot_css)) : ?>
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-day.ts-has-entry::after{ <?php echo esc_html($calendar_status_dot_css); ?> }
        <?php endif; ?>
        <?php if (!empty($calendar_hover_bg_css)) : ?>
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-day:hover{ <?php echo esc_html($calendar_hover_bg_css); ?> }
        <?php endif; ?>
        <?php if (!empty($calendar_selected_day_css)) : ?>
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-day.selected{ <?php echo esc_html($calendar_selected_day_css); ?> }
        <?php endif; ?>
        <?php if (!empty($calendar_weekdays_css)) : ?>
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-weekdays{ <?php echo esc_html($calendar_weekdays_css); ?> }
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-weekdays .flatpickr-weekday{ <?php echo esc_html($calendar_weekdays_css); ?> }
        <?php endif; ?>
        
        #fpCalendar-<?php echo esc_attr($uid);?> .flatpickr-innerContainer{ justify-content: center; }
        @media (min-width: 992px){ :root{ --fp-header-h: 56px; --fp-weekdays-h: 40px; --fp-day-size: 48px; } }
        #fpCurYear-<?php echo esc_attr($uid);?>{ width: 10ch; min-width: 10ch; text-align: center; }
        #fpHeader-<?php echo esc_attr($uid);?>{ text-align: center; border-bottom: 1px solid #dee2e6;}
        #fpYearWrapper-<?php echo esc_attr($uid);?>{ display: inline-flex; align-items: center; justify-content: center; min-width: 7ch; }
        #fpMonthSelect-<?php echo esc_attr($uid);?>{ min-width: 16ch; text-align-last: center; }
        @media (max-width: 576px){
          #fpMonthSelect-<?php echo esc_attr($uid);?>{ min-width: 7ch; }
          #fpCurYear-<?php echo esc_attr($uid);?>{ width: 7ch; min-width: 7ch; }
        }
        </style>

        <div id="calendarContainer-<?php echo esc_attr($uid);?>">
          <div id="fpCalendar-<?php echo esc_attr($uid);?>" aria-label="Kalender"></div>
          <input id="fpInput-<?php echo esc_attr($uid);?>" type="text" class="form-control mt-2" placeholder="TT.MM.JJJJ" autocomplete="off"<?php echo (!empty($calendar_input_css) ? ' style="' . esc_attr($calendar_input_css) . '"' : ''); ?> />
          <?php if (!empty($button_label)) : ?>
            <div class="mt-2"<?php echo (!empty($button_parent_css) ? ' style="' . esc_attr($button_parent_css) . '"' : ''); ?>>
              <?php if (!empty($left_button_label) && !empty($left_button_url)) : ?>
                <span<?php echo (!empty($left_button_parent_css) ? ' style="' . esc_attr($left_button_parent_css) . '"' : ''); ?>>
                  <a id="ts-calendar-left-btn-<?php echo esc_attr($uid);?>" class="btn btn-outline-secondary mr-2<?php echo (!empty($left_button_classes) ? ' ' . esc_attr($left_button_classes) : ''); ?>" href="<?php echo esc_url($left_button_url);?>"<?php echo (!empty($left_button_css) ? ' style="' . esc_attr($left_button_css) . '"' : ''); ?>><?php echo esc_html($left_button_label);?></a>
                </span>
              <?php endif; ?>
              <a id="ts-calendar-btn-<?php echo esc_attr($uid);?>" class="btn btn-primary<?php echo (!empty($button_classes) ? ' ' . esc_attr($button_classes) : ''); ?>"<?php echo (!empty($target_url) ? ' href="' . esc_url($target_url) . '"' : ''); ?><?php echo (!empty($button_css) ? ' style="' . esc_attr($button_css) . '"' : ''); ?>><?php echo esc_html($button_label);?></a>
            </div>
          <?php endif; ?>
        </div>

        <script>
        document.addEventListener('DOMContentLoaded', function () {
          if (!window.flatpickr) return;
          const fpInput = document.getElementById('fpInput-<?php echo esc_js($uid);?>');
          const fpCal = document.getElementById('fpCalendar-<?php echo esc_js($uid);?>');
          if (fpInput && fpCal) {
            // Erledigte Tage des aktuellen Monats (serverseitig vorab ermittelt)
            var tsDoneDates = new Set(<?php echo wp_json_encode(array_values(array_unique($initialDates))); ?>);

            const fpInstance = flatpickr(fpInput, {
              inline: true,
              appendTo: fpCal,
              clickOpens: false,
              locale: 'de',
              dateFormat: 'd.m.Y',
              allowInput: true,
                             onDayCreate: [function(dObj, dStr, fp, dayElem){
                 if (!tsDoneDates || tsDoneDates.size === 0) return;
                 try {
                   var dateObj = dayElem && dayElem.dateObj ? dayElem.dateObj : dObj;
                   var iso = (fp && typeof fp.formatDate === 'function') ? fp.formatDate(dateObj, 'Y-m-d') : (window.flatpickr && window.flatpickr.formatDate ? window.flatpickr.formatDate(dateObj, 'Y-m-d') : null);
                   if (iso && tsDoneDates.has(iso)) {
                     dayElem.classList.add('ts-has-entry');
                   }
                   
                   // Doppelklick-Event direkt auf den Tag setzen
                   if (dayElem && !dayElem.classList.contains('disabled')) {
                     dayElem.addEventListener('dblclick', function(e) {
                       e.preventDefault();
                       e.stopPropagation();
                       // Kurze Verzögerung um sicherzustellen, dass Flatpickr das Datum gesetzt hat
                       setTimeout(function() {
                         var btn = document.getElementById('ts-calendar-btn-<?php echo esc_js($uid);?>');
                         if (btn && btn.getAttribute('aria-disabled') !== 'true') {
                           btn.click();
                         }
                       }, 100);
                     });
                   }
                 } catch(e) {}
               }],
              onChange: [function(selectedDates, dateStr, instance) {
                // Kalender-Button URL mit ausgewähltem Datum aktualisieren
                var calendarBtn = document.getElementById('ts-calendar-btn-<?php echo esc_js($uid);?>');
                if (calendarBtn && selectedDates.length > 0) {
                  var selectedDate = selectedDates[0];
                  var formattedDate = selectedDate.getFullYear() + '-' + 
                                    String(selectedDate.getMonth() + 1).padStart(2, '0') + '-' + 
                                    String(selectedDate.getDate()).padStart(2, '0');
                  
                  // Nur fortfahren wenn eine Target URL vorhanden ist
                  var originalHref = calendarBtn.getAttribute('data-original-href');
                  if (!originalHref) {
                    // Beim ersten Mal die ursprüngliche URL speichern
                    originalHref = calendarBtn.getAttribute('href');
                    if (originalHref) {
                      calendarBtn.setAttribute('data-original-href', originalHref);
                    }
                  }
                  
                  // Ersetze den Platzhalter in der ursprünglichen URL (nur wenn URL vorhanden)
                  if (originalHref) {
                    var newHref = originalHref.replace('{{selected_date}}', formattedDate).replace('%7B%7Bselected_date%7D%7D', formattedDate);
                    calendarBtn.setAttribute('href', newHref);
                  }
                }
              }],
                             onReady: [function(){
                 markDoneDays();
               }]
            });

            // Client-Cache und Nachladen pro Monat
            var tsMonthCache = {}; // key: 'YYYY-MM' -> Set('YYYY-MM-DD')
            function tsKey(y, m){ return String(y) + '-' + ('0' + String(m)).slice(-2); }
            function tsAjaxUrl(){ return '<?php echo esc_js(admin_url('admin-ajax.php')); ?>'; }
            // Seed Cache für aktuellen Monat
            (function seed(){
              var y = fpInstance.currentYear; var m = fpInstance.currentMonth + 1;
              if (tsDoneDates.size > 0) { tsMonthCache[tsKey(y, m)] = new Set(Array.from(tsDoneDates)); }
            })();

            function ensureMonth(y, m, cb){
              var key = tsKey(y, m);
              if (tsMonthCache[key]) { if (cb) cb(tsMonthCache[key]); return; }
              var fd = new FormData();
              fd.append('action', 'calendar_get_month_entries');
              fd.append('calendar_id', '<?php echo (int)$id; ?>');
              fd.append('year', String(y));
              fd.append('month', String(m));
              fetch(tsAjaxUrl(), { method: 'POST', credentials: 'same-origin', body: fd })
                .then(function(r){ return r.json(); })
                .then(function(data){
                  var set = new Set();
                  if (data && Array.isArray(data.dates)) { data.dates.forEach(function(d){ set.add(d); }); }
                  tsMonthCache[key] = set;
                  if (cb) cb(set);
                })
                .catch(function(){ if (cb) cb(new Set()); });
            }

            function useMonthSet(y, m, set){
              tsDoneDates = set || new Set();
              markDoneDays();
            }

            fpInstance.set('onMonthChange', (fpInstance.config.onMonthChange || []).concat([function(){
              var y = fpInstance.currentYear; var m = fpInstance.currentMonth + 1;
              ensureMonth(y, m, function(set){ useMonthSet(y, m, set); });
            }]));

            fpInstance.set('onYearChange', (fpInstance.config.onYearChange || []).concat([function(){
              var y = fpInstance.currentYear; var m = fpInstance.currentMonth + 1;
              ensureMonth(y, m, function(set){ useMonthSet(y, m, set); });
            }]));

            const calRoot = fpCal.querySelector('.flatpickr-calendar');
            if (calRoot) calRoot.id = 'fpCalendarWidget-<?php echo esc_js($uid);?>';
            try {
              if (calRoot) {
                // Zusatz-Klassen für Widget
                var extraClasses = <?php echo wp_json_encode($calendar_widget_classes); ?>;
                if (extraClasses && typeof extraClasses === 'string') {
                  extraClasses.split(/\s+/).filter(Boolean).forEach(function(c){ calRoot.classList.add(c); });
                }
                // Zusatz-Styles für Widget
                var extraStyle = <?php echo wp_json_encode($calendar_widget_css); ?>;
                if (extraStyle && typeof extraStyle === 'string') {
                  calRoot.setAttribute('style', (calRoot.getAttribute('style')||'') + (extraStyle ? ';' + extraStyle : ''));
                }
              }
            } catch(e){}
            const header = calRoot && calRoot.querySelector('.flatpickr-months');
            if (header) header.id = 'fpHeader-<?php echo esc_js($uid);?>';
            const prevBtn = calRoot && calRoot.querySelector('.flatpickr-prev-month');
            if (prevBtn) prevBtn.id = 'fpPrev-<?php echo esc_js($uid);?>';
            const nextBtn = calRoot && calRoot.querySelector('.flatpickr-next-month');
            if (nextBtn) nextBtn.id = 'fpNext-<?php echo esc_js($uid);?>';
            const curMonth = calRoot && calRoot.querySelector('.flatpickr-current-month .cur-month');
            if (curMonth) curMonth.id = 'fpCurMonth-<?php echo esc_js($uid);?>';
            const curYear = calRoot && calRoot.querySelector('.flatpickr-current-month .numInput.cur-year');
            if (curYear) {
              curYear.id = 'fpCurYear-<?php echo esc_js($uid);?>';
              curYear.setAttribute('inputmode','numeric');
              curYear.setAttribute('aria-label','Jahr');
            }
            const yearWrapper = calRoot && calRoot.querySelector('.flatpickr-current-month .numInputWrapper');
            if (yearWrapper) yearWrapper.id = 'fpYearWrapper-<?php echo esc_js($uid);?>';
            const monthSelect = calRoot && calRoot.querySelector('.flatpickr-monthDropdown-months');
            if (monthSelect) monthSelect.id = 'fpMonthSelect-<?php echo esc_js($uid);?>';

            function markDoneDays(){
              var root = document.getElementById('fpCalendarWidget-<?php echo esc_js($uid);?>');
              if (!root || tsDoneDates.size === 0) return;
              var y = fpInstance.currentYear;
              var m0 = fpInstance.currentMonth; // 0-11
              var days = root.querySelectorAll('.flatpickr-day');
              days.forEach(function(el){
                el.classList.remove('ts-has-entry');
                var dn = parseInt(el.textContent, 10);
                if (!dn || isNaN(dn)) return;
                var yy = y, mm0 = m0;
                if (el.classList.contains('prevMonthDay')) { mm0 = (m0 + 11) % 12; if (m0 === 0) yy = y - 1; }
                else if (el.classList.contains('nextMonthDay')) { mm0 = (m0 + 1) % 12; if (m0 === 11) yy = y + 1; }
                var ds = yy + '-' + ('0' + (mm0+1)).slice(-2) + '-' + ('0' + dn).slice(-2);
                if (tsDoneDates.has(ds)) {
                  el.classList.add('ts-has-entry');
                }
              });
            }

            markDoneDays();

            // Button-Klick: weiterleiten mit Params calendar_id und date (YYYY-MM-DD)
            var btn = document.getElementById('ts-calendar-btn-<?php echo esc_js($uid);?>');
            if (btn) {
              // Helper to truly disable/enable anchor
              function setAnchorDisabled(anchor, disabled){
                if (disabled){
                  anchor.setAttribute('aria-disabled','true');
                  anchor.classList.add('disabled');
                  anchor.style.pointerEvents = 'none';
                  anchor.tabIndex = -1;
                } else {
                  anchor.removeAttribute('aria-disabled');
                  anchor.classList.remove('disabled');
                  anchor.style.pointerEvents = '';
                  anchor.tabIndex = 0;
                }
              }

              // initial disabled, wenn kein Datum
              var hasDate = (fpInstance && fpInstance.selectedDates && fpInstance.selectedDates.length > 0);
              setAnchorDisabled(btn, !hasDate);

              // Toggle per Flatpickr onChange
              fpInstance.set('onChange', (fpInstance.config.onChange || []).concat([function(selectedDates){
                setAnchorDisabled(btn, !(selectedDates && selectedDates.length > 0));
              }]));

              // Toggle bei manueller Eingabe
              fpInput.addEventListener('input', function(){
                var parsed = flatpickr.parseDate(fpInput.value, 'd.m.Y');
                setAnchorDisabled(btn, !parsed);
              });

              btn.addEventListener('click', function(e){
                if (btn.getAttribute('aria-disabled') === 'true') { e.preventDefault(); return; }
                e.preventDefault();
                var baseUrl = this.getAttribute('href') || '';
                var selDate = '';
                if (fpInstance && fpInstance.selectedDates && fpInstance.selectedDates.length > 0) {
                  selDate = fpInstance.formatDate(fpInstance.selectedDates[0], 'Y-m-d');
                } else if (fpInput && fpInput.value) {
                  var parsed = flatpickr.parseDate(fpInput.value, 'd.m.Y');
                  if (parsed) selDate = flatpickr.formatDate(parsed, 'Y-m-d');
                }
                var url = new URL(baseUrl, window.location.origin);
                url.searchParams.set('calendar_id', '<?php echo (int)$id; ?>');
                if (selDate) url.searchParams.set('date', selDate);
                window.location.assign(url.toString());
              });
            }
          }
        });
        </script>
        <?php
        return ob_get_clean();
    }
}


