/* =============================================
   HELLION NEWTAB — timer.js
   Timer / Countdown Widget: Presets, Alarm,
   Tab-Titel-Blink
   ============================================= */

const Timer = {
  WIDGET_ID: 'widget_timer',
  STORAGE_KEY: 'widgetStates',
  MAX_PRESETS: 5,

  /** @type {Array<{name: string, seconds: number}>} */
  _presets: [],
  _isOpen: false,
  _seconds: 0,
  _remaining: 0,
  _intervalId: null,
  _running: false,
  _finished: false,
  _blinkIntervalId: null,
  _originalTitle: '',
  _keydownHandler: null,
  _muted: false,

  // UI-Referenzen
  _timeEl: null,
  _muteBtn: null,
  _inputEl: null,
  _inputRow: null,
  _btnStart: null,
  _btnPause: null,
  _btnReset: null,

  // ---- STORAGE ----

  /**
   * Timer-State aus Storage laden
   */
  async load() {
    const data = await Store.get(this.STORAGE_KEY);
    if (data && data.timer) {
      this._presets = Array.isArray(data.timer.presets) ? data.timer.presets : [];
      if (typeof data.timer.muted === 'boolean') this._muted = data.timer.muted;
    }
  },

  /**
   * Timer-State in Storage speichern
   * Bestehende Notes + Calculator bleiben erhalten
   */
  async save() {
    const data = await Store.get(this.STORAGE_KEY) || {};
    if (data.notes === undefined) data.notes = [];

    const widgetState = WidgetManager.getState(this.WIDGET_ID);
    data.timer = {
      x: widgetState ? widgetState.x : 600,
      y: widgetState ? widgetState.y : 80,
      width: widgetState ? widgetState.width : 260,
      height: widgetState ? widgetState.height : 360,
      open: this._isOpen,
      presets: this._presets.slice(0, this.MAX_PRESETS),
      muted: this._muted
    };

    await Store.set(this.STORAGE_KEY, data);
  },

  // ---- WIDGET LIFECYCLE ----

  /**
   * Timer-Widget oeffnen oder in Vordergrund bringen
   */
  async open() {
    if (this._isOpen) {
      WidgetManager.bringToFront(this.WIDGET_ID);
      return;
    }

    const data = await Store.get(this.STORAGE_KEY);
    const saved = (data && data.timer) ? data.timer : {};

    WidgetManager.create('timer', {
      id: this.WIDGET_ID,
      title: t('timer.title'),
      x: saved.x || 600,
      y: saved.y || 80,
      width: saved.width || 260,
      height: saved.height || 360,
      open: true
    });

    const body = WidgetManager.getBody(this.WIDGET_ID);
    if (body) this.renderBody(body);

    this._isOpen = true;

    const entry = WidgetManager._widgets.get(this.WIDGET_ID);
    if (entry) this._bindKeyboard(entry.el);

    await this.save();
  },

  /**
   * Timer toggle: oeffnen oder minimieren
   */
  async toggle() {
    if (this._isOpen) {
      const entry = WidgetManager._widgets.get(this.WIDGET_ID);
      if (entry && entry.state.open) {
        await WidgetManager.minimize(this.WIDGET_ID);
        this._isOpen = false;
        await this.save();
      } else if (entry) {
        await WidgetManager.openWidget(this.WIDGET_ID);
        this._isOpen = true;
        await this.save();
      }
    } else {
      await this.open();
    }
  },

  /**
   * Wird aufgerufen wenn Widget geschlossen wird
   */
  async onClose() {
    this._isOpen = false;
    this._unbindKeyboard();
    this._stopCountdown();
    this._stopAlarm();
    this._timeEl = null;
    this._inputEl = null;
    this._inputRow = null;
    this._btnStart = null;
    this._btnPause = null;
    this._btnReset = null;
    this._muteBtn = null;
    await this.save();
  },

  // ---- UI RENDERING ----

  /**
   * Timer-Body rendern
   * @param {HTMLElement} bodyEl
   */
  renderBody(bodyEl) {
    bodyEl.textContent = '';
    bodyEl.style.padding = '8px';
    bodyEl.style.display = 'flex';
    bodyEl.style.flexDirection = 'column';

    // Display
    const display = document.createElement('div');
    display.className = 'timer-display';

    const timeEl = document.createElement('div');
    timeEl.className = 'timer-time';
    timeEl.textContent = '00:00';
    this._timeEl = timeEl;
    display.appendChild(timeEl);

    // Input
    const inputRow = document.createElement('div');
    inputRow.className = 'timer-input-row';
    this._inputRow = inputRow;

    const input = document.createElement('input');
    input.className = 'timer-input';
    input.type = 'text';
    input.placeholder = 'mm:ss';
    input.maxLength = 8;
    this._inputEl = input;

    input.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') {
        e.preventDefault();
        this._applyInput();
        this._start();
      }
    });

    inputRow.appendChild(input);

    // Controls
    const controls = document.createElement('div');
    controls.className = 'timer-controls';

    const btnStart = document.createElement('button');
    btnStart.className = 'timer-ctrl-btn primary';
    btnStart.type = 'button';
    btnStart.textContent = t('timer.start');
    btnStart.addEventListener('click', () => {
      if (!this._running && this._remaining === 0) {
        this._applyInput();
      }
      this._start();
    });
    this._btnStart = btnStart;

    const btnPause = document.createElement('button');
    btnPause.className = 'timer-ctrl-btn';
    btnPause.type = 'button';
    btnPause.textContent = t('timer.pause');
    btnPause.disabled = true;
    btnPause.addEventListener('click', () => this._pause());
    this._btnPause = btnPause;

    const btnReset = document.createElement('button');
    btnReset.className = 'timer-ctrl-btn danger';
    btnReset.type = 'button';
    btnReset.textContent = t('timer.reset');
    btnReset.addEventListener('click', () => this._reset());
    this._btnReset = btnReset;

    controls.append(btnStart, btnPause, btnReset);

    // Mute Toggle (in Controls-Zeile)
    const muteBtn = document.createElement('button');
    muteBtn.className = 'timer-mute-btn';
    muteBtn.type = 'button';
    this._muteBtn = muteBtn;
    this._updateMuteBtn();
    muteBtn.addEventListener('click', async () => {
      this._muted = !this._muted;
      this._updateMuteBtn();
      await this.save();
    });
    controls.appendChild(muteBtn);

    // Presets
    const presetsEl = this._createPresetsPanel();

    bodyEl.append(display, inputRow, controls, presetsEl);

    // State wiederherstellen
    this._updateDisplay();
    this._updateControls();
  },

  /**
   * Presets-Panel erstellen
   * @returns {HTMLElement}
   */
  _createPresetsPanel() {
    const container = document.createElement('div');
    container.className = 'timer-presets';
    container.id = 'timerPresetsPanel';

    const header = document.createElement('div');
    header.className = 'timer-presets-header';

    const title = document.createElement('span');
    title.className = 'timer-presets-title';
    title.textContent = t('timer.presets');

    const addBtn = document.createElement('button');
    addBtn.className = 'timer-preset-add';
    addBtn.type = 'button';
    addBtn.textContent = '+';
    addBtn.title = t('timer.save_preset');
    addBtn.addEventListener('click', () => this._showAddPreset(container));

    header.append(title, addBtn);
    container.appendChild(header);

    this._renderPresetItems(container);

    return container;
  },

  /**
   * Preset-Items rendern
   * @param {HTMLElement} container
   */
  _renderPresetItems(container) {
    // Alte Items entfernen
    const oldItems = container.querySelectorAll('.timer-preset-item, .timer-add-row');
    oldItems.forEach(item => item.remove());

    this._presets.forEach((preset, idx) => {
      const item = document.createElement('div');
      item.className = 'timer-preset-item';

      const name = document.createElement('span');
      name.className = 'timer-preset-name';
      name.textContent = preset.name;

      const time = document.createElement('span');
      time.className = 'timer-preset-time';
      time.textContent = this._formatTime(preset.seconds);

      const del = document.createElement('button');
      del.className = 'timer-preset-del';
      del.type = 'button';
      del.textContent = '\u2715';
      del.addEventListener('click', async (e) => {
        e.stopPropagation();
        await this._deletePreset(idx);
        this._renderPresetItems(container);
      });

      item.append(name, time, del);

      // Klick laedt Preset
      item.addEventListener('click', () => {
        this._loadPreset(preset);
      });

      container.appendChild(item);
    });
  },

  /**
   * Add-Preset UI anzeigen
   * @param {HTMLElement} container
   */
  _showAddPreset(container) {
    // Nur einmal anzeigen
    if (container.querySelector('.timer-add-row')) return;

    if (this._presets.length >= this.MAX_PRESETS) {
      HellionDialog.alert(
        t('timer.limit_message', { max: this.MAX_PRESETS }),
        { type: 'warning', title: t('timer.limit_title') }
      );
      return;
    }

    // Aktuelle Zeit als Vorlage
    const currentSeconds = this._remaining > 0 ? this._seconds : 0;
    if (currentSeconds === 0 && this._inputEl) {
      const parsed = this._parseTimeInput(this._inputEl.value);
      if (parsed === 0) {
        HellionDialog.alert(
          t('timer.no_time_message'),
          { type: 'info', title: t('timer.no_time_title') }
        );
        return;
      }
    }

    const row = document.createElement('div');
    row.className = 'timer-add-row';

    const nameInput = document.createElement('input');
    nameInput.className = 'timer-add-input';
    nameInput.type = 'text';
    nameInput.placeholder = t('timer.preset_name_placeholder');
    nameInput.maxLength = 20;

    const confirmBtn = document.createElement('button');
    confirmBtn.className = 'timer-add-confirm';
    confirmBtn.type = 'button';
    confirmBtn.textContent = t('timer.ok');

    const doAdd = async () => {
      const name = nameInput.value.trim();
      if (!name) return;

      let secs = this._seconds;
      if (secs === 0 && this._inputEl) {
        secs = this._parseTimeInput(this._inputEl.value);
      }
      if (secs === 0) return;

      await this._addPreset(name, secs);
      this._renderPresetItems(container);
    };

    confirmBtn.addEventListener('click', doAdd);
    nameInput.addEventListener('keydown', (e) => {
      if (e.key === 'Enter') doAdd();
      if (e.key === 'Escape') row.remove();
    });

    row.append(nameInput, confirmBtn);
    container.appendChild(row);
    nameInput.focus();
  },

  // ---- TIMER LOGIC ----

  /**
   * Input-Feld auslesen und als Sekunden setzen
   */
  _applyInput() {
    if (!this._inputEl) return;
    const secs = this._parseTimeInput(this._inputEl.value);
    if (secs > 0) {
      this._seconds = secs;
      this._remaining = secs;
    }
  },

  /**
   * Timer starten
   */
  _start() {
    if (this._running) return;
    if (this._remaining <= 0) return;

    // Falls gerade Alarm laeuft, stoppen
    if (this._finished) {
      this._stopAlarm();
      this._finished = false;
    }

    this._running = true;
    this._updateControls();

    // Input verstecken
    if (this._inputRow) this._inputRow.style.display = 'none';

    this._intervalId = setInterval(() => this._tick(), 1000);
  },

  /**
   * Timer pausieren
   */
  _pause() {
    if (!this._running) return;
    this._running = false;
    this._stopCountdown();
    this._updateControls();
  },

  /**
   * Timer zuruecksetzen
   */
  _reset() {
    this._stopCountdown();
    this._stopAlarm();
    this._running = false;
    this._finished = false;
    this._remaining = 0;
    this._seconds = 0;

    // Input wieder anzeigen
    if (this._inputRow) this._inputRow.style.display = 'flex';
    if (this._inputEl) this._inputEl.value = '';

    this._updateDisplay();
    this._updateControls();
  },

  /**
   * Jede Sekunde: remaining verringern, Display aktualisieren
   */
  _tick() {
    this._remaining--;

    if (this._remaining <= 0) {
      this._remaining = 0;
      this._stopCountdown();
      this._running = false;
      this._finished = true;
      this._onFinish();
    }

    this._updateDisplay();
    this._updateControls();
  },

  /**
   * Interval stoppen
   */
  _stopCountdown() {
    if (this._intervalId) {
      clearInterval(this._intervalId);
      this._intervalId = null;
    }
  },

  /**
   * Timer abgelaufen — Alarm + Tab-Blink
   */
  _onFinish() {
    if (!this._muted) this._playAlarm();
    this._startTitleBlink();
  },

  /**
   * Akustisches Signal (Browser Audio API, kein externer Request)
   */
  _playAlarm() {
    try {
      const ctx = new AudioContext();
      [0, 0.3, 0.6].forEach(delay => {
        const osc = ctx.createOscillator();
        const gain = ctx.createGain();
        osc.connect(gain);
        gain.connect(ctx.destination);
        osc.frequency.value = 800;
        gain.gain.value = 0.07;
        osc.start(ctx.currentTime + delay);
        osc.stop(ctx.currentTime + delay + 0.2);
      });
    } catch (e) {
      console.warn('Timer: Audio nicht verfuegbar', e);
    }
  },

  /**
   * Tab-Titel blinken lassen
   */
  _startTitleBlink() {
    this._originalTitle = document.title;
    this._blinkIntervalId = setInterval(() => {
      document.title = document.title === t('timer.finished_title')
        ? this._originalTitle
        : t('timer.finished_title');
    }, 1000);
  },

  /**
   * Tab-Titel Blink und Alarm stoppen
   */
  _stopAlarm() {
    if (this._blinkIntervalId) {
      clearInterval(this._blinkIntervalId);
      this._blinkIntervalId = null;
      document.title = this._originalTitle || t('timer.default_page_title');
    }
    this._finished = false;
    this._updateDisplay();
    this._updateControls();
  },

  /**
   * Mute-Button Text/Titel aktualisieren
   */
  _updateMuteBtn() {
    if (!this._muteBtn) return;
    this._muteBtn.textContent = this._muted ? '\uD83D\uDD07' : '\uD83D\uDD0A';
    this._muteBtn.title = this._muted ? t('timer.unmute') : t('timer.mute');
    this._muteBtn.classList.toggle('muted', this._muted);
  },

  // ---- DISPLAY ----

  /**
   * Zeitanzeige aktualisieren
   */
  _updateDisplay() {
    if (!this._timeEl) return;
    this._timeEl.textContent = this._formatTime(this._remaining);
    this._timeEl.classList.toggle('finished', this._finished);
  },

  /**
   * Button-States aktualisieren
   */
  _updateControls() {
    if (this._btnStart) {
      this._btnStart.disabled = this._running;
      this._btnStart.textContent = this._finished ? t('timer.restart') : t('timer.start');
    }
    if (this._btnPause) {
      this._btnPause.disabled = !this._running;
    }
  },

  // ---- PRESETS ----

  /**
   * Preset hinzufuegen
   * @param {string} name
   * @param {number} seconds
   */
  async _addPreset(name, seconds) {
    if (this._presets.length >= this.MAX_PRESETS) return;
    this._presets.push({ name, seconds });
    await this.save();
  },

  /**
   * Preset loeschen
   * @param {number} index
   */
  async _deletePreset(index) {
    this._presets.splice(index, 1);
    await this.save();
  },

  /**
   * Preset laden (Zeit setzen)
   * @param {Object} preset - { name, seconds }
   */
  _loadPreset(preset) {
    // Falls laufend, erst stoppen
    this._stopCountdown();
    this._stopAlarm();
    this._running = false;
    this._finished = false;

    this._seconds = preset.seconds;
    this._remaining = preset.seconds;

    if (this._inputRow) this._inputRow.style.display = 'none';

    this._updateDisplay();
    this._updateControls();
  },

  // ---- FORMATTING ----

  /**
   * Sekunden in Zeitformat umwandeln
   * @param {number} totalSeconds
   * @returns {string} "05:30" oder "1:05:30"
   */
  _formatTime(totalSeconds) {
    const h = Math.floor(totalSeconds / 3600);
    const m = Math.floor((totalSeconds % 3600) / 60);
    const s = totalSeconds % 60;

    const mm = String(m).padStart(2, '0');
    const ss = String(s).padStart(2, '0');

    if (h > 0) {
      return h + ':' + mm + ':' + ss;
    }
    return mm + ':' + ss;
  },

  /**
   * Zeit-String in Sekunden parsen
   * Akzeptiert: "5:30", "05:30", "1:05:30", "90" (Sekunden)
   * @param {string} str
   * @returns {number}
   */
  _parseTimeInput(str) {
    const trimmed = (str || '').trim();
    if (!trimmed) return 0;

    const parts = trimmed.split(':');

    if (parts.length === 1) {
      // Nur Zahl = Sekunden
      const secs = parseInt(parts[0], 10);
      return isNaN(secs) ? 0 : Math.max(0, secs);
    }

    if (parts.length === 2) {
      // mm:ss
      const m = parseInt(parts[0], 10);
      const s = parseInt(parts[1], 10);
      if (isNaN(m) || isNaN(s)) return 0;
      return Math.max(0, m * 60 + s);
    }

    if (parts.length === 3) {
      // hh:mm:ss
      const h = parseInt(parts[0], 10);
      const m = parseInt(parts[1], 10);
      const s = parseInt(parts[2], 10);
      if (isNaN(h) || isNaN(m) || isNaN(s)) return 0;
      return Math.max(0, h * 3600 + m * 60 + s);
    }

    return 0;
  },

  // ---- KEYBOARD ----

  /**
   * Tastatur-Events binden
   * @param {HTMLElement} widgetEl
   */
  _bindKeyboard(widgetEl) {
    this._unbindKeyboard();

    this._keydownHandler = (e) => {
      // Nicht reagieren wenn User in Input tippt
      if (e.target.tagName === 'INPUT') return;

      if (e.key === ' ' || e.key === 'Enter') {
        e.preventDefault();
        if (this._running) {
          this._pause();
        } else if (this._remaining > 0) {
          this._start();
        }
      } else if (e.key === 'Escape' || e.key === 'r' || e.key === 'R') {
        e.preventDefault();
        this._reset();
      }
    };

    widgetEl.addEventListener('keydown', this._keydownHandler);
    widgetEl.tabIndex = 0;
  },

  /**
   * Keyboard-Events entfernen
   */
  _unbindKeyboard() {
    if (this._keydownHandler) {
      const entry = WidgetManager._widgets.get(this.WIDGET_ID);
      if (entry) {
        entry.el.removeEventListener('keydown', this._keydownHandler);
      }
      this._keydownHandler = null;
    }
  },

  // ---- INIT ----

  /**
   * Timer initialisieren (aus app.js aufgerufen)
   */
  async init() {
    await this.load();

    // Wenn Timer beim letzten Mal offen war, wiederherstellen
    const data = await Store.get(this.STORAGE_KEY);
    if (data && data.timer && data.timer.open) {
      await this.open();
    }

    // Widget-Lifecycle-Events
    const self = this;
    WidgetManager.on('widget:close', (e) => {
      if (e.detail.id === self.WIDGET_ID) {
        self.onClose();
      }
    });

    WidgetManager.on('widget:minimize', (e) => {
      if (e.detail.id === self.WIDGET_ID) {
        self._isOpen = false;
        self.save();
      }
    });

    WidgetManager.on('widget:open', (e) => {
      if (e.detail.id === self.WIDGET_ID) {
        self._isOpen = true;
        const body = WidgetManager.getBody(self.WIDGET_ID);
        if (body && body.children.length === 0) {
          self.renderBody(body);
        }
        const entry = WidgetManager._widgets.get(self.WIDGET_ID);
        if (entry) self._bindKeyboard(entry.el);
        self.save();
      }
    });
  }
};
