import {
  Component,
  OnInit,
  OnDestroy,
  HostListener,
  ChangeDetectorRef,
  HostBinding,
  AfterViewInit,
  Renderer2,
  NgZone
} from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { DomSanitizer, SafeHtml } from '@angular/platform-browser';
import { interval, Subject, throwError, lastValueFrom, Subscription, of } from 'rxjs';
import { switchMap, takeUntil, distinctUntilChanged, tap, catchError, map, take } from 'rxjs/operators';

import { AvisoService, AvisoArrivalsResponse } from '../../services/aviso.service';
import { AvisoDto, TvSettings } from '../../services/aviso.dto';
import { AvisoTvTextSettingsDto } from '../../services/aviso-tv-settings.dto';

interface AvisoResolvedData {
  avisoTvTextSettings: AvisoTvTextSettingsDto[];
  avisoTvSettings: TvSettings[];
  arrivals: AvisoArrivalsResponse;
  standortID: number;
}

interface CssVariables {
  tileWidthPercent: string;
  tileHeightVh: string;
  tileTitleFontSize: string;
  tileFontSizeDateTime: string;
  tileSeitenwechselInSek: string;
  textBalkenHeightVh: string;
  tileRowGapinPercent: string;
  flaggeLeft: string;
  flaggeBottom: string;
  reload: string;
}

const TVTEXTSETTINGS_INTERVAL_MS = 60000;
const TVSETTINGS_INTERVAL_MS = 10000;
const TOGGLE_DIV_INTERVAL_MS = 5000;

//Wechseltext
const WECHSELTEXT = "BITTE KOMMEN / LÜTFEN GELIN";

interface StatusInfo {
  class: string;
  icon: string;
  color: string;
  text: string;
}

const STATUS_MAP: { [key: string]: StatusInfo } = {
  '3': { class: 'statusLKW_Ankunft', icon: 'time', color: 'medium', text: 'Ankunft' },
  'lkwfertig': { class: 'lkwfertig', icon: 'time', color: 'warning', text: 'Ankunft' },
  'fehlt': { class: 'fehlt', icon: 'time', color: 'danger', text: 'Dokument Fehlt' },
  'default': { class: 'status-default', icon: 'help-circle', color: 'medium', text: 'Unbekannt' }
};

interface SettingDisplayData {
  nonEmptyFixeZeilen: {
    sanitizedHtml: SafeHtml;
    textAlign: string;
  }[];
  currentDivIndex: number;
  isDivReady: boolean;
}

@Component({
  selector: 'app-aviso',
  templateUrl: './aviso.page.html',
  styleUrls: ['./aviso.page.scss'],
})
export class AvisoPage implements OnInit, OnDestroy, AfterViewInit {

  @HostBinding('style.--tile-width-percent') tileWidthPercent = '50vw';
  @HostBinding('style.--tile-height-vh') tileHeightVh = '40vh';
  @HostBinding('style.--tile-title-font-size') tileTitleFontSize = '5vh';
  @HostBinding('style.--tile-font-size-date-time') tileFontSizeDateTime = '5vh';
  @HostBinding('style.--text-balken-height-vh') textBalkenHeightVh = '10vh';
  @HostBinding('style.--tile-row-gap') tileRowGapinPercent = '10px';
  @HostBinding('style.--text-flagge-left') flaggeLeft = '10px';
  @HostBinding('style.--text-flagge-bottom') flaggeBottom = '10px';

  progressBarValue: number = 0;
  private progressBarSubscription: Subscription = new Subscription();

  currentDate: Date = new Date();
  private dateSubscription: Subscription = new Subscription();

  private durationSubscription: Subscription = new Subscription();
  private pageRotationSubscription: Subscription | null = null;

  standort = '';
  standortID = 0;
  seiten = true;
  onlyOK = false;

  arrivals: AvisoDto[] = [];
  avisoTvTextSettings: AvisoTvTextSettingsDto[] = [];
  avisoTvSettings: TvSettings[] = [];

  pages: AvisoDto[][] = [];
  currentPageIndex = 0;
  tilesPerPage = 0;

  loadingArrivals = false;
  loadingTextSettings = false;
  loadingTvSettings = false;

  totalArrivals = 0;
  totalTextSettings = 0;

  errorMessage = '';
  settingsErrorMessage = '';

  private destroy$ = new Subject<void>();
  private toggleDivInterval: any;
  private currentCssVariables: CssVariables | null = null;

 
  public toggleWechselText: boolean = false;
  private GLOBAL_WECHSELTEXT_INTERVAL: any;

  // Zeiten für Hint-/Normal-Anzeige
  contentDuration = 3000;
  avisoHinweisDuration = 1500;

  // Anzeigedaten für die Fixe-Zeilen im oberen Bereich
  settingDisplayData: SettingDisplayData[] = [];

  // Zustände für AVISOs (z.B. ob normaler Inhalt vs. Warnhinweis gezeigt wird)
  avisoTimeouts: { [key: string]: any } = {};
  avisoStates: { [key: string]: boolean } = {};

  // Falls neue Arrivals schon geladen, aber noch nicht aktiv
  pendingArrivals: AvisoDto[] | null = null;

  constructor(
    private route: ActivatedRoute,
    private avisoService: AvisoService,
    private cdr: ChangeDetectorRef,
    private sanitizer: DomSanitizer,
    private renderer: Renderer2,
    private ngZone: NgZone 
  ) { }

  private convertToPx(fontSize: string): number {
    if (fontSize.endsWith('pt')) {
      return parseFloat(fontSize) * 1.333;
    } else if (fontSize.endsWith('px')) {
      return parseFloat(fontSize);
    } else {
      return parseFloat(fontSize);
    }
  }

  ngOnInit() {
    this.route.paramMap.subscribe(params => {
      this.standort = params.get('standort') || '';
    });

    this.route.queryParamMap.subscribe(queryParams => {
      this.standort = queryParams.get('standort') || 'NEU';
      this.seiten = queryParams.get('seiten') === 'true';
      this.onlyOK = queryParams.get('onlyOK') === 'true';
    });

    this.route.data
      .pipe(takeUntil(this.destroy$))
      .subscribe((resolvedData) => {
        const data = (resolvedData as any)['avisoData'] as AvisoResolvedData;
        this.avisoTvTextSettings = data.avisoTvTextSettings;
        this.avisoTvSettings = data.avisoTvSettings;
        this.arrivals = data.arrivals.avisos;
        this.totalArrivals = data.arrivals.totalCount;
        this.standortID = data.standortID;

        this.paginateArrivals();
        this.cdr.detectChanges();
        this.preprocessHtmlSettings();
        this.setCSSVariables();
        this.startDivToggle();
        this.paginateArrivals();
        this.startPageRotation();
        this.updateAvisoStatesAndCycles();
      });

    // Arrivals zyklisch neu laden
    const ARRIVALS_INTERVAL_MS = (this.avisoTvSettings[0]?.seitenwechselInSek * 1000 / 2) || 5000;
    interval(ARRIVALS_INTERVAL_MS)
      .pipe(
        switchMap(() => {
          this.loadingArrivals = this.arrivals.length === 0;
          this.errorMessage = '';
          return this.avisoService.getArrivals(this.standort, this.onlyOK).pipe(
            catchError((error) => {
              this.errorMessage = 'Fehler beim Laden der Arrivals. Bitte versuche es später erneut.';
              this.loadingArrivals = false;
              return of({ avisos: [], totalCount: 0 });
            })
          );
        }),
        distinctUntilChanged((prev, curr) => this.arrivalsAreEqual(prev.avisos, curr.avisos)),
        takeUntil(this.destroy$)
      )
      .subscribe((data: AvisoArrivalsResponse) => {
        this.loadingArrivals = false;
        if (this.pages.length > 1) {
          // Bei mehreren Seiten erst mit dem nächsten Seitenwechsel übernehmen
          this.pendingArrivals = data.avisos;
          this.totalArrivals = data.totalCount;
        } else {
          // Bei nur einer Seite direkt übernehmen
          this.arrivals = data.avisos;
          this.totalArrivals = data.totalCount;
          this.paginateArrivals();
          this.cdr.detectChanges();
          this.updateAvisoStatesAndCycles();
        }
      });

    // TV Settings laden
    interval((this.avisoTvSettings[0]?.seitenwechselInSek * 1000 - 1000) || TVSETTINGS_INTERVAL_MS)
      .pipe(
        switchMap(() => this.loadAvisoTvSettings()),
        takeUntil(this.destroy$)
      )
      .subscribe();

    // TV Text Settings laden
    interval(TVTEXTSETTINGS_INTERVAL_MS)
      .pipe(
        switchMap(() => this.loadAvisoTvTextSettings()),
        takeUntil(this.destroy$)
      )
      .subscribe();

    // Sekündliche Uhrzeit
    this.currentDate = new Date();
    this.dateSubscription = interval(1000).subscribe(() => {
      this.currentDate = new Date();
    });

    // Dauerberechnung aller Arrivals
    this.updateDurations();
    this.durationSubscription = interval(60000).subscribe(() => {
      this.updateDurations();
    });

    // Globaler Wechseltext für alle fertigen LKWs ohne Hinweis
    this.GLOBAL_WECHSELTEXT_INTERVAL = setInterval(() => {
      this.toggleWechselText = !this.toggleWechselText;
      this.cdr.detectChanges();
    }, 3000);
  }

  ngAfterViewInit() {
  }

  ngOnDestroy() {
    this.destroy$.next();
    this.destroy$.complete();

    // Zeitgeber aufräumen
    Object.values(this.avisoTimeouts).forEach(timeoutId => clearTimeout(timeoutId));
    this.avisoTimeouts = {};

    if (this.toggleDivInterval) {
      clearInterval(this.toggleDivInterval);
    }
    if (this.progressBarSubscription) {
      this.progressBarSubscription.unsubscribe();
    }
    if (this.dateSubscription) {
      this.dateSubscription.unsubscribe();
    }
    if (this.durationSubscription) {
      this.durationSubscription.unsubscribe();
    }
    if (this.GLOBAL_WECHSELTEXT_INTERVAL) {
      clearInterval(this.GLOBAL_WECHSELTEXT_INTERVAL);
    }
  }

  // Dauer (h/m) berechnen
  private updateDurations(): void {
    const currentYear = new Date().getFullYear();
    const currentDate = new Date();
    this.arrivals.forEach(aviso => {
      if (aviso.ankunft) {
        const [tagMonat, uhrzeit] = aviso.ankunft.split(' ');
        const [tag, monat] = tagMonat.split('.');
        const [stunden, minuten] = uhrzeit.split(':');
        const arrivalDate = new Date(
          currentYear,
          parseInt(monat) - 1,
          parseInt(tag),
          parseInt(stunden),
          parseInt(minuten)
        );
        const diffMs = currentDate.getTime() - arrivalDate.getTime();
        if (diffMs >= 0) {
          const diffMinutes = Math.floor(diffMs / 60000);
          const hours = Math.floor(diffMinutes / 60);
          const mins = diffMinutes % 60;
          aviso.dauer = `${hours}h ${mins}m`;
        } else {
          aviso.dauer = '0h 0m';
        }
      }
    });
    this.cdr.detectChanges();
  }

  private startProgressBar(seitenwechselInSek: number): void {
    if (this.progressBarSubscription) {
      this.progressBarSubscription.unsubscribe();
    }
    this.progressBarValue = 0;
    const progressBarIntervalMs = 100;
    const totalSteps = Math.floor((seitenwechselInSek * 1000) / progressBarIntervalMs);

    this.progressBarSubscription = interval(progressBarIntervalMs)
      .pipe(
        take(totalSteps),
        map((step) => (step + 1) / totalSteps),
        takeUntil(this.destroy$)
      )
      .subscribe((progress) => {
        this.progressBarValue = progress;
        this.cdr.detectChanges();
      });
  }

  getOverallIndex(i: number): number {
    let count = 0;
    for (let j = 0; j < this.currentPageIndex; j++) {
      count += this.pages[j].length;
    }
    return count + i + 1;
  }

  private preprocessHtmlSettings() {
    this.settingDisplayData = this.avisoTvTextSettings.map((setting, index) => ({
      nonEmptyFixeZeilen: this.getNonEmptyFixeZeilen(setting),
      currentDivIndex: 0,
      isDivReady: true
    }));
  }

  private getNonEmptyFixeZeilen(setting: AvisoTvTextSettingsDto) {
    const nonEmptyFixeZeilen = [];

    if (setting.fixeZeile1) {
      const { sanitizedHtml, textAlign } = this.processHtml(setting.fixeZeile1, setting);
      nonEmptyFixeZeilen.push({ sanitizedHtml, textAlign });
    }

    if (setting.fixeZeile2) {
      const { sanitizedHtml, textAlign } = this.processHtml(setting.fixeZeile2, setting);
      nonEmptyFixeZeilen.push({ sanitizedHtml, textAlign });
    }

    if (setting.fixeZeile3) {
      const { sanitizedHtml, textAlign } = this.processHtml(setting.fixeZeile3, setting);
      nonEmptyFixeZeilen.push({ sanitizedHtml, textAlign });
    }

    return nonEmptyFixeZeilen;
  }

  private processHtml(html: string, setting: AvisoTvTextSettingsDto): { sanitizedHtml: SafeHtml; textAlign: string } {
    const parser = new DOMParser();
    const doc = parser.parseFromString(html, 'text/html');
    const firstDiv = doc.querySelector('div');
    let textAlign = 'left';
    const divs = doc.querySelectorAll('div');
    divs.forEach(div => {
      const fontSize = div.style.fontSize;
      if (fontSize) {
        const fontSizePx = this.convertToPx(fontSize);
        textAlign = div.style.textAlign || 'left';
        div.dataset['originalFontSizePx'] = fontSizePx.toString();
        div.dataset['originalTextAlign'] = textAlign;
      }
      div.style.fontSize = '';
      div.classList.add('dynamic-font-size');
    });
    if (firstDiv) {
      textAlign = firstDiv.style.textAlign || 'left';
    }
    const sanitizedHtml = this.sanitizer.bypassSecurityTrustHtml(doc.body.innerHTML);
    return { sanitizedHtml, textAlign };
  }

  private setCSSVariables(): void {
    if (this.avisoTvSettings && this.avisoTvSettings.length > 0) {
      const settings = this.avisoTvSettings[0];
      const newCssVariables: CssVariables = {
        tileWidthPercent: `${settings.kachelWidthInPercent}vw`,
        tileHeightVh: `${settings.kachelHeightInPercent}vh`,
        tileTitleFontSize: `${settings.kachelFontSizeLkwNummer}vh`,
        tileFontSizeDateTime: `${settings.kachelFontSizeDateTime}vh`,
        tileSeitenwechselInSek: `${settings.seitenwechselInSek}s`,
        textBalkenHeightVh: `${settings.textBalkenHeightInPercent}vh`,
        tileRowGapinPercent: `${settings.kachelRowGapInPercent}px`,
        flaggeLeft: `${settings.flaggeLeft}vw`,
        flaggeBottom: `${settings.flaggeBottom}vh`,
        reload: `${settings.reload}`,
      };

      if (this.currentCssVariables && this.hasCssVariablesChanged(newCssVariables)) {
        this.reloadPageOnce();
        return;
      }
      Object.assign(this, newCssVariables);
      this.currentCssVariables = newCssVariables;
    } else {
      console.warn('Fehler CSS Variablen');
    }
  }

  private hasCssVariablesChanged(newVars: CssVariables): boolean {
    return Object.keys(newVars).some(key => (newVars as any)[key] !== (this.currentCssVariables as any)[key]);
  }

  private async loadAvisoTvSettings(): Promise<void> {
    this.loadingTvSettings = true;
    try {
      await lastValueFrom(
        this.avisoService.getAvisoTvSettings(this.standortID).pipe(
          tap((data: TvSettings[]) => {
            this.avisoTvSettings = data;
            this.loadingTvSettings = false;
            this.setCSSVariables();
          }),
          catchError((error: any) => this.handleSettingsError(error, 'TV Settings'))
        )
      );
    } catch {
      // Fehler bereits behandelt
    }
  }

  private async loadAvisoTvTextSettings(): Promise<void> {
    this.loadingTextSettings = true;
    try {
      await lastValueFrom(
        this.avisoService.getAvisoTvTextSettings(this.standort).pipe(
          tap((data: AvisoTvTextSettingsDto[]) => {
            this.avisoTvTextSettings = data;
            this.totalTextSettings = data.length;
            this.loadingTextSettings = false;
            this.preprocessHtmlSettings();
          }),
          catchError((error: any) => this.handleSettingsError(error, 'TV Text Settings'))
        )
      );
    } catch {
      // Fehler bereits behandelt
    }
  }

  private handleSettingsError(error: any, context: string) {
    console.error(`Fehler beim Laden der ${context}:`, error);
    this.settingsErrorMessage = `Fehler beim Laden der ${context}. Bitte versuche es später erneut.`;
    this.loadingTvSettings = false;
    this.loadingTextSettings = false;
    return throwError(error);
  }

  private startDivToggle(): void {
    const shouldToggle = this.settingDisplayData.some(data => data.nonEmptyFixeZeilen.length > 1);
    if (shouldToggle) {
      this.toggleDivInterval = setInterval(() => {
        this.settingDisplayData.forEach((data, index) => {
          if (data.nonEmptyFixeZeilen.length > 1) {
            this.settingDisplayData[index].isDivReady = false;
            data.currentDivIndex = (data.currentDivIndex + 1) % data.nonEmptyFixeZeilen.length;
          }
        });
        this.cdr.detectChanges();
      }, TOGGLE_DIV_INTERVAL_MS);
    } else {
      this.settingDisplayData.forEach((data, index) => {
        data.currentDivIndex = 0;
        data.isDivReady = true;
      });
    }
  }

  getStatusClass(status: number, lkwFertig: boolean, avisoTvhinweis: string): string {
    if (lkwFertig && avisoTvhinweis === "") {
      return STATUS_MAP['lkwfertig'].class;
    } else if (avisoTvhinweis != "") {
      return STATUS_MAP['fehlt'].class;
    } else if (avisoTvhinweis != "" && lkwFertig) {
      return STATUS_MAP['fehlt'].class;
    }
    return STATUS_MAP[status.toString()]?.class || STATUS_MAP['default'].class;
  }

  getStatusIcon(status: number): string {
    return STATUS_MAP[status.toString()]?.icon || STATUS_MAP['default'].icon;
  }

  getTvHinweisImgSrc(avisotvhinweis: string): string {
    if (avisotvhinweis.toLowerCase() == "passport") {
      return "assets/warnings/passport.png";
    }
    else if (avisotvhinweis.toLowerCase() == "problem") {
      return "assets/warnings/urgent.png";
    }
    else {
      return "assets/warnings/urgent.png";
    }
  }

  getStatusColor(status: number): string {
    return STATUS_MAP[status.toString()]?.color || STATUS_MAP['default'].color;
  }

  getStatusText(status: number): string {
    return STATUS_MAP[status.toString()]?.text || STATUS_MAP['default'].text;
  }

  private reloadPageOnce(): void {
    if (!sessionStorage.getItem('pageReloaded')) {
      sessionStorage.setItem('pageReloaded', 'true');
      window.location.reload();
    } else {
      sessionStorage.removeItem('pageReloaded');
    }
  }

  private paginateArrivals(): void {
    if (!this.avisoTvSettings || this.avisoTvSettings.length === 0) {
      return;
    }
    const settings = this.avisoTvSettings[0];
    const windowWidth = window.innerWidth;
    const windowHeight = window.innerHeight;

    const isMobileDevice = () => {
      const mobileBreakpoint = 768;
      return windowWidth <= mobileBreakpoint;
    };

    if (isMobileDevice()) {
      // Keine Mehrseiten-Darstellung bei kleinen Geräten
      this.pages = [this.arrivals];
      this.tilesPerPage = this.arrivals.length;
      this.currentPageIndex = 0;
      return;
    }

    const allFixeZeilenEmpty = this.settingDisplayData.every(data => data.nonEmptyFixeZeilen.length === 0);

    let effectiveTileHeightPercent = settings.kachelHeightInPercent;
    let htmltextHeight = (settings.textBalkenHeightInPercent / 100) * windowHeight;

    if (allFixeZeilenEmpty) {
      htmltextHeight = 0;
    }

    const tileWidth = (settings.kachelWidthInPercent / 100) * windowWidth;
    const tileHeight = (effectiveTileHeightPercent / 100) * windowHeight;

    const logo = (10 / 100) * windowHeight;
    const gutterHorizontal = (1 / 100) * windowHeight;
    const gutterVertical = (1 / 100) * windowHeight;
    const containerPadding = (0 / 100) * windowHeight;
    const containerPaddingTotal = containerPadding * 2;

    // Anzahl Spalten
    const columns = Math.floor(
      (windowWidth - containerPaddingTotal + gutterHorizontal) / (tileWidth + gutterHorizontal)
    ) || 1;

    // Platz für Zeilen berechnen
    const availableHeightForTiles =
      windowHeight -
      logo -
      htmltextHeight -
      containerPadding * 2 -
      gutterVertical * (columns > 1 ? columns : 0);

    const rows = Math.floor(
      (availableHeightForTiles + gutterVertical) / (tileHeight + gutterVertical)
    ) || 1;

    this.tilesPerPage = columns * rows;
    this.tilesPerPage = this.tilesPerPage > 0 ? this.tilesPerPage : 1;

    this.pages = [];
    for (let i = 0; i < this.arrivals.length; i += this.tilesPerPage) {
      this.pages.push(this.arrivals.slice(i, i + this.tilesPerPage));
    }

    if (this.currentPageIndex >= this.pages.length) {
      this.currentPageIndex = 0;
    }
    this.updateAvisoStatesAndCycles();


  }

  private startPageRotation(): void {
    // Prüfen, ob wir überhaupt mehrere Seiten haben
    if (!this.avisoTvSettings || this.avisoTvSettings.length === 0) {
      console.warn('avisoTvSettings ist nicht verfügbar oder leer');
      return;
    }
    if (this.pages.length <= 1) {
      // Nur eine Seite => keine Rotation
      return;
    }

    const seitenwechselInSek = this.avisoTvSettings[0].seitenwechselInSek;
    if (typeof seitenwechselInSek === 'number' && seitenwechselInSek > 0) {
      const intervalMs = seitenwechselInSek * 1000;

      // Progress-Bar einmalig starten
      this.startProgressBar(seitenwechselInSek);

      // Falls noch eine alte Subscription läuft, vorher beenden
      this.stopPageRotationIfRunning();

      // Jetzt neue Subscription anlegen
      this.pageRotationSubscription = interval(intervalMs)
        .pipe(takeUntil(this.destroy$))
        .subscribe(() => {
          // Neue Arrivals erst beim Seitenwechsel übernehmen
          if (this.pendingArrivals) {
            this.arrivals = this.pendingArrivals;
            this.pendingArrivals = null;
            this.paginateArrivals();
            this.cdr.detectChanges();
          }

          if (this.pages.length > 1) {
            this.currentPageIndex = (this.currentPageIndex + 1) % this.pages.length;
            this.cdr.detectChanges();

            // Progress-Bar für nächste Runde (Seitenwechsel) erneut starten
            this.startProgressBar(seitenwechselInSek);
          } else {
            console.warn('Keine ausreichende Anzahl von Seiten zum Wechseln');
          }
        });
    } else {
      console.warn('seitenwechselInSek ist ungültig:', seitenwechselInSek);
    }

    if (this.pages.length > 1) {
       this.restartPageRotationIfNeeded();
    } else {
       this.stopPageRotationIfRunning();
    }
  }


  private stopPageRotationIfRunning(): void {
    if (this.pageRotationSubscription && !this.pageRotationSubscription.closed) {
      this.pageRotationSubscription.unsubscribe();
      this.pageRotationSubscription = null;
    }
  }

  private restartPageRotationIfNeeded(): void {
     if (!this.pageRotationSubscription || this.pageRotationSubscription.closed) {
      this.startPageRotation();
    }
  }


  @HostListener('window:resize')
  onResizeHostListener(): void {
    this.paginateArrivals();
  }

  private arrivalsAreEqual(a: AvisoDto[], b: AvisoDto[]): boolean {
    if (a.length !== b.length) {
      return false;
    }
    for (let i = 0; i < a.length; i++) {
      const aItem = a[i];
      const bItem = b[i];
      if (
        aItem.avisoID !== bItem.avisoID ||
        aItem.status !== bItem.status ||
        aItem.lkW_Nr !== bItem.lkW_Nr ||
        aItem.ankunft !== bItem.ankunft ||
        aItem.letzterMitarbeiter !== bItem.letzterMitarbeiter ||
        aItem.imEx !== bItem.imEx ||
        aItem.buero !== bItem.buero ||
        aItem.avisoTVHinweis !== bItem.avisoTVHinweis
      ) {
        return false;
      }
    }
    return true;
  }

  private updateAvisoStatesAndCycles(): void {
    const currentKeys = new Set<string>();

    this.arrivals.forEach(aviso => {
      const key = aviso.lkW_Nr;
      currentKeys.add(key);
      if (aviso.avisoTVHinweis) {
        // Hat das Aviso einen Hinweis, dann abwechseln
        if (!(key in this.avisoStates)) {
          this.avisoStates[key] = true;
          this.startAvisoCycle(key);
        }
      } else {
        // Kein Hinweis => immer normal
        this.avisoStates[key] = true;
      }
    });

    // Alte Keys entfernen
    Object.keys(this.avisoStates).forEach(key => {
      if (!currentKeys.has(key)) {
        clearTimeout(this.avisoTimeouts[key]);
        delete this.avisoStates[key];
        delete this.avisoTimeouts[key];
      }
    });
  }

  private startAvisoCycle(key: string): void {
    const aviso = this.findAvisoByKey(key);
    if (!aviso || !aviso.avisoTVHinweis) {
      return;
    }

     if (this.avisoStates[key]) {
      this.avisoTimeouts[key] = setTimeout(() => {
        this.ngZone.run(() => {  
          this.avisoStates[key] = false;
          this.startAvisoCycle(key);
          this.cdr.detectChanges();
        });
      }, this.contentDuration);
    } else {
      this.avisoTimeouts[key] = setTimeout(() => {
        this.ngZone.run(() => {
          this.avisoStates[key] = true;
          this.startAvisoCycle(key);
          this.cdr.detectChanges();
        });
      }, this.avisoHinweisDuration);
    }
  }


  private findAvisoByKey(key: string): AvisoDto | undefined {
    for (const page of this.pages) {
      for (const aviso of page) {
        if (aviso.lkW_Nr === key) {
          return aviso;
        }
      }
    }
    return undefined;
  }

  // Falls kein Hinweis: immer "normalen" Content,
  // sonst Umschalten zwischen normal und Hinweis
  shouldShowNormalContent(aviso: AvisoDto): boolean {
    if (!aviso.avisoTVHinweis) {
      return true;
    }
    return this.avisoStates[aviso.lkW_Nr];
  }

  getImageForTab(index: number): string {
    const images = [
      'assets/flags/DE.gif',
      'assets/flags/EN.gif',
      'assets/flags/TR.gif',
    ];
    return images[index] || 'assets/imgs/DE.png';
  }

  onResizeComplete(index: number): void {
    this.settingDisplayData[index].isDivReady = true;
    this.cdr.detectChanges();
  }

  getImageClass(hinweis: string): string {
    const lowercaseHinweis = hinweis.toLowerCase();
    if (lowercaseHinweis === 'problem') {
      return 'problem';
    } else if (lowercaseHinweis === 'passport') {
      return 'passport';
    } else if (lowercaseHinweis != '') {
      return 'problem';
    } else {
      return '';
    }
  }

  getImageClassButtomLeft(hinweis: string): string {
    const lowercaseHinweis = hinweis.toLowerCase();
    if (lowercaseHinweis === 'problem') {
      return 'bottom-left-image-problem';
    } else if (lowercaseHinweis === 'passport') {
      return 'bottom-left-image-passport';
    } else {
      return '';
    }
  }
}
