/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */

import { MozLitElement } from "chrome://global/content/lit-utils.mjs";
import { html } from "chrome://global/content/vendor/lit.all.mjs";
import { countryName } from "chrome://browser/content/ipprotection/ipprotection-utils.mjs";

/**
 * A custom element that renders the single-select list of egress locations.
 */
export default class LocationsList extends MozLitElement {
  static properties = {
    locations: { type: Array },
    selectedLocation: { type: String, state: true },
  };

  static defaultLocation = "REC";

  static collator = new Intl.Collator(undefined, { sensitivity: "base" });

  get #sortedLocations() {
    return Array.from(this.locations ?? []).sort((a, b) => {
      const nameA = countryName(a.code) ?? a.code;
      const nameB = countryName(b.code) ?? b.code;
      return LocationsList.collator.compare(nameA, nameB);
    });
  }

  constructor() {
    super();
    this.selectedLocation = "";
    this.locations = [];
  }

  createRenderRoot() {
    return this;
  }

  connectedCallback() {
    super.connectedCallback();
  }

  getSelectedLocation() {
    if (
      !this.selectedLocation ||
      (this.selectedLocation !== LocationsList.defaultLocation &&
        !this.locations?.some(l => l.code === this.selectedLocation))
    ) {
      return LocationsList.defaultLocation;
    }
    return this.selectedLocation;
  }

  handleSelectLocation(code) {
    if (this.selectedLocation === code) {
      return;
    }
    this.selectedLocation = code;
    this.dispatchEvent(
      new CustomEvent("IPProtection:UserSelectLocation", {
        bubbles: true,
        composed: true,
        detail: { code },
      })
    );
  }

  #locationRow(aLocation) {
    const isSelected = aLocation.code === this.getSelectedLocation();
    return html`
      <li role="presentation">
        <button
          class="location-item subviewbutton"
          role="radio"
          id="location-option-${aLocation.code}"
          aria-checked=${isSelected ? "true" : "false"}
          @click=${() => this.handleSelectLocation(aLocation.code)}
          ?disabled=${!aLocation.available}
        >
          <img
            class="location-check"
            src="chrome://global/skin/icons/check.svg"
            aria-hidden="true"
          />
          <span class="location-label-group">
            ${aLocation.code === LocationsList.defaultLocation
              ? html`<span
                    id="location-label-recommended"
                    class="location-label"
                    data-l10n-id="ipprotecion-locations-subview-recommended-label"
                  ></span>
                  <span
                    class="location-description"
                    data-l10n-id="ipprotection-locations-subview-recommended-description"
                  ></span>`
              : html`<span class="location-label"
                  >${countryName(aLocation.code)}</span
                >`}
          </span>
          ${!aLocation.available
            ? html`
                <span
                  class="location-unavailable-label"
                  data-l10n-id="ipprotection-locations-unavailable-label"
                ></span>
              `
            : null}
        </button>
      </li>
    `;
  }

  render() {
    const recommendedLocation = {
      code: LocationsList.defaultLocation,
      available: true,
    };

    return html`
      <div id="locations-list-wrapper">
        <span
          id="locations-list-description"
          data-l10n-id="ipprotection-locations-subview-description"
        ></span>
        <ul
          id="locations-list"
          role="radiogroup"
          aria-labelledby="locations-list-description"
        >
          ${this.#locationRow(recommendedLocation)}
          ${this.#sortedLocations.map(aLocation =>
            this.#locationRow(aLocation)
          )}
        </ul>
      </div>
    `;
  }
}

customElements.define("locations-list", LocationsList);
