import streamDeck, { SingletonAction } from "@elgato/streamdeck";
import { wsManager } from "../websocket-manager.js";
import { generateSaveButton } from "../image-generator.js";

/**
 * Save Playlist Action
 *
 * Saves the current playlist with all timestamps.
 * Shows brief visual feedback after save (success or error).
 */
export class SaveAction extends SingletonAction {
  manifestId = "com.djliveplaylist.save";

  // Store action references for updating button images
  actions = new Map();

  constructor() {
    super();

    // Update buttons when connection state changes
    wsManager.on("connected", () => this.updateAllButtons());
    wsManager.on("disconnected", () => this.updateAllButtons());

    // Listen for save result from the app
    wsManager.on("SAVE_RESULT", (payload) => {
      this.handleSaveResult(payload);
    });
  }

  onWillAppear(ev) {
    const actionId = ev.action.id;
    this.actions.set(actionId, {
      action: ev.action,
      feedbackTimeout: null,
    });
    this.updateButton(actionId);
  }

  onWillDisappear(ev) {
    const actionId = ev.action.id;
    const entry = this.actions.get(actionId);
    if (entry?.feedbackTimeout) {
      clearTimeout(entry.feedbackTimeout);
    }
    this.actions.delete(actionId);
  }

  async onKeyDown(ev) {
    if (!wsManager.isConnected) {
      streamDeck.logger.warn("Cannot save: not connected to DLP");
      return;
    }

    wsManager.send("SAVE_PLAYLIST", {});
    streamDeck.logger.info("Save playlist requested");
  }

  handleSaveResult(payload) {
    const state = payload.success ? "saved" : "error";

    // Show feedback on all buttons briefly
    for (const [actionId, entry] of this.actions.entries()) {
      // Clear any existing feedback timeout
      if (entry.feedbackTimeout) {
        clearTimeout(entry.feedbackTimeout);
      }

      // Show feedback
      const image = generateSaveButton({
        isConnected: wsManager.isConnected,
        state,
      });
      entry.action.setImage(image);

      // Return to idle after 2 seconds
      entry.feedbackTimeout = setTimeout(() => {
        entry.feedbackTimeout = null;
        this.updateButton(actionId);
      }, 2000);
    }

    if (payload.success) {
      streamDeck.logger.info("Playlist saved successfully");
    } else {
      streamDeck.logger.warn("Playlist save failed:", payload.message);
    }
  }

  async updateButton(actionId) {
    const entry = this.actions.get(actionId);
    if (!entry) return;

    const image = generateSaveButton({
      isConnected: wsManager.isConnected,
      state: "idle",
    });
    entry.action.setImage(image);
  }

  updateAllButtons() {
    for (const actionId of this.actions.keys()) {
      this.updateButton(actionId);
    }
  }
}
