export interface Channel {
  id: string;
  name: string;
  provider: string;
}

export class ScheduleChannelStorage {
  private storageKey: string = "schedule:channels";

  getAll(): Channel[] {
    const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
    return Object.values(objects);
  }

  add(object: Channel) {
    const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
    objects[object.id] = object;
    window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
  }

  remove(id: string) {
    const objects = JSON.parse(window.localStorage.getItem(this.storageKey) || "{}");
    delete objects[id];
    window.localStorage.setItem(this.storageKey, JSON.stringify(objects));
  }
}

export class ScheduleChannelManager {
  loadChannels(selector: string) {
    const channels = window.scheduleChannelStorage.getAll();
    const container = document.querySelector(selector);
    if (container) {
      container.innerHTML = "";
      for (const channel of channels) {
        const element = new ScheduleChannelElement();
        element.setAttribute("channel", JSON.stringify(channel));
        element.setAttribute("removable", "");
        container.appendChild(element);
      }
    }
  }
}

class ScheduleChannelElement extends HTMLElement {
  static observedAttributes = ["channel", "removable"];

  channel: Channel | null = null;

  constructor() {
    super();
    this.handleClick = this.handleClick.bind(this);
    this.handleRemoveClick = this.handleRemoveClick.bind(this);
  }

  connectedCallback() {
    this.channel = JSON.parse(this.getAttribute("channel") || "{}");
    this.innerHTML = `
    <a href="${this.channel?.provider}/${this.channel?.id}"
      class="d-flex justify-content-between align-items-start  text-decoration-none">
      <span>
        <span class="text-primary">${this.channel?.name}</span>
      </span>
      <span>
        <span class="badge text-bg-secondary">${this.channel?.provider}</span>
        <span class="text-danger ms-2" data-remove>
          &#x2715;
        </span>
      </span>
    </a>`;
    this.classList = "list-group-item list-group-item-action";
    this.addEventListener("click", this.handleClick);
    if (this.hasAttribute("removable")) {
      this.querySelector<HTMLElement>("[data-remove]")?.addEventListener("click", this.handleRemoveClick);
    } else {
      this.querySelector("[data-remove]")?.remove();
    }
  }

  disconnectedCallback() {
    this.removeEventListener("click", this.handleClick);
    this.querySelector<HTMLElement>("[data-remove]")?.removeEventListener("click", this.handleRemoveClick);
  }

  handleClick(event: MouseEvent) {
    if (this.channel) {
      window.scheduleChannelStorage.add(this.channel);
    }
  }

  handleRemoveClick(event: MouseEvent) {
    event.preventDefault();
    event.stopPropagation();
    if (this.channel) {
      window.scheduleChannelStorage.remove(this.channel.id);
    }
    this.remove();
  }
}

customElements.define("schedule-channel", ScheduleChannelElement);

declare global {
  interface Window {
    scheduleChannelStorage: ScheduleChannelStorage;
    scheduleChannelManager: ScheduleChannelManager;
  }
}

window.scheduleChannelStorage = new ScheduleChannelStorage();
window.scheduleChannelManager = new ScheduleChannelManager();
