// Main Settings Component Class - PRESTOplay Version
import { clpp } from "@castlabs/prestoplay";
import {
  playbackSpeedIcon,
  qualityIcon,
  subtitleIcon,
  chevronLeftIcon,
} from "../../../assets/icons/index.js";
import {
  formatQualityLabel,
  sortQualityTracks,
} from "../../../utils/renditionHelper.js";
import { createButton } from "../../../utils/buttonFactory.js";

const AUTO_QUALITY_ID = -1;
const DEFAULT_QUALITY = {
  value: AUTO_QUALITY_ID,
  label: "Auto",
};

const SUBTITLE_OFF_ID = "off";
const DEFAULT_SUBTITLE = {
  value: SUBTITLE_OFF_ID,
  label: "Off",
};

export class SettingsComponent {
  constructor(player) {
    this.player = player;

    this.container = null;
    this.settingsBtn = null;
    this.settingsPopup = null;
    this.isPopupOpen = false;

    // Settings data
    this.speeds = [
      { value: 0.5, label: "0.5x" },
      { value: 0.75, label: "0.75x" },
      { value: 1, label: "Normal" },
      { value: 1.25, label: "1.25x" },
      { value: 1.5, label: "1.5x" },
      { value: 2, label: "2x" },
    ];
    this.currentSpeed = { value: 1, label: "Normal" };

    this.renditions =
      this.player
        ?.getTrackManager()
        ?.getVideoTracks()[0]
        ?.renditions?.filter(
          (r) => typeof r.id && r.width && r.height && r.bandwidth
        )
        ?.sort(sortQualityTracks)
        ?.map((rendition) => ({
          value: rendition.id,
          label: formatQualityLabel(rendition),
        })) ?? [];
    this.renditions.unshift(DEFAULT_QUALITY);
    this.currentRendition = DEFAULT_QUALITY;

    this.subtitles =
      this.player
        ?.getTrackManager()
        ?.getTextTracks()
        ?.map((track) => ({
          value: track.language,
          kind: track.kind,
          label: track.label || track.language || "Unknown",
          language: track.language || "unknown",
        })) ?? [];
    this.subtitles.unshift(DEFAULT_SUBTITLE);
    this.currentSubtitle = DEFAULT_SUBTITLE;

    this.init();
  }

  init() {
    this.createElements();
    this.setupEventListeners();
    this.showMainMenu();
  }

  createElements() {
    // Settings wrapper
    this.container = document.createElement("div");
    this.container.className = "pp-settings-container";

    // Settings button
    this.settingsBtn = createButton("settings", "Settings", (e) => {
      e.stopPropagation();
      if (this.isPopupOpen) {
        this.hideSettingsPopup();
      } else {
        this.showSettingsPopup();
      }
    });

    // Settings popup (initially hidden)
    this.settingsPopup = document.createElement("div");
    this.settingsPopup.className = "pp-settings-popup pp-display-none";

    this.container.appendChild(this.settingsBtn);
    this.container.appendChild(this.settingsPopup);
  }

  createMainMenu() {
    const mainMenuOptions = [
      {
        action: "playback-speed",
        icon: playbackSpeedIcon,
        title: "Playback speed",
        value: this.currentSpeed.label,
      },
      {
        action: "quality",
        icon: qualityIcon,
        title: "Quality",
        value: this.currentRendition.label,
      },
      {
        action: "subtitles",
        icon: subtitleIcon,
        title: "Subtitles",
        value: this.currentSubtitle.label,
      },
    ];

    return mainMenuOptions
      .map(
        (option) => `
          <div class="pp-settings-item" data-action="${option.action}">
            <div class="pp-settings-item-icon">${option.icon}</div>
            <span class="pp-settings-item-title">${option.title}</span>
            <span class="pp-settings-item-value">${option.value}</span>
          </div>
        `
      )
      .join("");
  }

  createSubmenu(title, action, options, selectedOption) {
    return `
      ${this.createBackButton(title)}
      ${options
        .map((option) => {
          const selected = option.value == selectedOption.value;
          return `
              <div class="pp-settings-item${
                selected ? " selected" : ""
              }" data-${action}="${option.value}">
                  <span>${option.label}</span>
                  ${selected ? `<span class="pp-checkmark-color">✓</span>` : ""}
              </div>
            `;
        })
        .join("")}
    `;
  }

  createBackButton(title) {
    return `
      <div class="pp-settings-item" data-action="back">
        ${chevronLeftIcon}
        <span>${title}</span>
      </div>
    `;
  }

  handleInteraction(e) {
    e.stopPropagation();

    const item = e.target.closest(".pp-settings-item");
    if (!item) return;

    const action = item.dataset.action;
    const speed = item.dataset.speed;
    const quality = item.dataset.quality;
    const subtitle = item.dataset.subtitle;

    if (action === "playback-speed") {
      this.settingsPopup.innerHTML = this.createSubmenu(
        "Playback speed",
        "speed",
        this.speeds,
        this.currentSpeed
      );
    } else if (action === "quality") {
      this.settingsPopup.innerHTML = this.createSubmenu(
        "Quality",
        "quality",
        this.renditions,
        this.currentRendition
      );
    } else if (action === "subtitles") {
      this.settingsPopup.innerHTML = this.createSubmenu(
        "Subtitles",
        "subtitle",
        this.subtitles,
        this.currentSubtitle
      );
    } else if (action === "back") {
      this.showMainMenu();
    } else if (speed) {
      this.setPlaybackSpeed(parseFloat(speed));
    } else if (quality) {
      this.setQuality(quality);
    } else if (subtitle) {
      this.setSubtitle(subtitle);
    }
  }

  setupEventListeners() {
    this.settingsPopup.addEventListener("click", (e) =>
      this.handleInteraction(e)
    );

    this.settingsPopup.addEventListener("touchend", (e) => {
      e.preventDefault();
      this.handleInteraction(e);
    });

    this.player.on(clpp.events.TEXT_TRACK_CHANGED, () =>
      this.updateCurrentSubtitle()
    );
  }

  showMainMenu() {
    this.settingsPopup.innerHTML = this.createMainMenu();
  }

  setPlaybackSpeed(speed) {
    this.currentSpeed = this.speeds.find((s) => s.value == speed);
    this.player.setPlaybackRate(speed);
    this.hideSettingsPopup();
  }

  setQuality(qualityId) {
    try {
      const rendition =
        this.renditions.find((r) => r.value == qualityId) || null;
      if (!rendition) return;

      this.currentRendition = rendition;

      const trackManager = this.player.getTrackManager();
      if (qualityId == AUTO_QUALITY_ID) {
        trackManager.setVideoRendition(null);
      } else {
        const originalRendition = trackManager
          .getVideoTracks()[0]
          .renditions.find((r) => r.id == qualityId);
        if (!originalRendition) return;

        trackManager.setVideoRendition(originalRendition);
      }
    } catch (error) {
      console.warn("Could not set quality:", error);
    } finally {
      this.hideSettingsPopup();
    }
  }

  setSubtitle(subtitleId) {
    try {
      const subtitle = this.subtitles.find((s) => s.value == subtitleId);
      if (!subtitle) return;

      this.currentSubtitle = subtitle;

      const trackManager = this.player.getTrackManager();
      if (subtitle.value === SUBTITLE_OFF_ID) {
        trackManager.setTextTrack(null);
      } else {
        const subtitleTrack = trackManager
          .getTextTracks()
          .find((s) => s.language == subtitleId);
        if (!subtitleTrack) return;

        trackManager.setTextTrack(subtitleTrack);
      }
    } catch (error) {
      console.warn("Could not set subtitle:", error);
    } finally {
      this.hideSettingsPopup();
    }
  }

  updateCurrentSubtitle() {
    const trackManager = this.player.getTrackManager();
    const textTrack = trackManager.getTextTrack();
    if (textTrack) {
      this.currentSubtitle =
        this.subtitles.find((s) => s.value == textTrack.language) ??
        DEFAULT_SUBTITLE;
    } else {
      this.currentSubtitle = DEFAULT_SUBTITLE;
    }
  }

  showSettingsPopup() {
    this.settingsPopup.classList.remove("pp-display-none");
    this.settingsPopup.classList.add("pp-display-block");
    this.isPopupOpen = true;
    this.showMainMenu();

    this.settingsTimeout = setTimeout(() => {
      const outsideHandler = (evt) => {
        if (
          !this.settingsPopup.contains(evt.target) &&
          !this.settingsBtn.contains(evt.target)
        ) {
          this.hideSettingsPopup();
        }
      };
      document.addEventListener("click", outsideHandler);
    }, 0);
  }

  hideSettingsPopup() {
    this.settingsPopup.classList.add("pp-display-none");
    this.settingsPopup.classList.remove("pp-display-block");
    this.isPopupOpen = false;
  }

  cleanup() {
    if (this.settingsTimeout) {
      clearTimeout(this.settingsTimeout);
    }
    this.player.off(clpp.events.TEXT_TRACK_CHANGED, () =>
      this.updateCurrentSubtitle()
    );

    // TODO: Add cleanup for event listeners
  }
}
