export interface Location {
  id: string;
  name: string;
  provider: string;
  country_code: string;
  country?: string;
  district?: string;
  subdistrict?: string;
}

export class WeatherLocationStorage {
  private storageKey: string = "weather:locations";

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

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

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

export class WeatherLocationManager {
  loadLocations(selector: string) {
    const locations = window.weatherLocationStorage.getAll();
    const container = document.querySelector(selector);
    if (container) {
      container.innerHTML = "";
      for (const location of locations) {
        const element = new WeatherLocationElement();
        element.setAttribute("location", JSON.stringify(location));
        element.setAttribute("removable", "");
        container.appendChild(element);
      }
    }
  }
}

class WeatherLocationElement extends HTMLElement {
  static observedAttributes = ["location", "removable"];

  location: Location | null = null;

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

  connectedCallback() {
    this.location = JSON.parse(this.getAttribute("location") || "{}");
    this.innerHTML = `
    <a href="${this.location?.provider}/${this.location?.id}"
      class="d-flex justify-content-between align-items-start text-decoration-none">
      <span>
        <span class="fi fi-${this.location?.country_code} me-1"></span>
        <span class="text-primary">${this.location?.name}</span>
        <span class="small ms-1 text-secondary">
          ${this.location?.country}, ${this.location?.district}, ${this.location?.subdistrict}
        </span>
      </span>
      <span>
        <span class="badge text-bg-secondary">${this.location?.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.location) {
      window.weatherLocationStorage.add(this.location);
    }
  }

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

customElements.define("weather-location", WeatherLocationElement);

declare global {
  interface Window {
    weatherLocationStorage: WeatherLocationStorage;
    weatherLocationManager: WeatherLocationManager;
  }
}

window.weatherLocationStorage = new WeatherLocationStorage();
window.weatherLocationManager = new WeatherLocationManager();
