// Imports
import * as Auth from "/services/auth/auth.js";
import * as Common from "/services/common/common.js";
import * as Messages from "/services/messages/messages.js";
import { Delete } from "/services/common/delete.js";

// DOM elements

// local variables
let current_user;

export async function mount(where, parent) {
  const areaComponent = new Area(parent);
  await areaComponent.mount(where);
  return areaComponent;
}

class Area {
  constructor(parent) {
    this.parent = parent;
  }

  async mount(where) {
    const mountpoint = where;
    document.getElementById(mountpoint).innerHTML = /* HTML */ `
      <header class="card-header">
        <p class="card-header-title" id="area-title">
          Circonscriptions
        </p>
        <button id="area-new" class="button is-success" disabled>
          <span class="icon is-small">
            <i class="fas fa-plus"></i>
          </span>
        </button>
      </header>
      <div class="card-content">
        <div id="area-list" class="content">
          Sélectionner une élection.
        </div>
      </div>
    `;
    current_user = await Auth.GetUser();
    this.mountModal("area-modal");
    this.handleDom();
  }

  handleDom() {
    let areaHandler = this;
    document.getElementById(`area-new`).addEventListener("click", function () {
      areaHandler.newArea(areaHandler.election);
    });

    document
      .getElementById(`area-modal-close`)
      .addEventListener("click", function () {
        Common.toggleModal("area-modal", "area-modal-card");
      });
    document
      .getElementById(`area-modal-cancel`)
      .addEventListener("click", function () {
        Common.toggleModal("area-modal", "area-modal-card");
      });
    document
      .getElementById(`area-modal-save`)
      .addEventListener("click", async function () {
        await areaHandler.saveArea();
      });
    document
      .getElementById(`area-modal-save-area`)
      .addEventListener("click", async function () {
        await areaHandler.saveArea();
        await new Promise((r) => setTimeout(r, 800));
        areaHandler.newArea(areaHandler.election);
      });
    document
      .getElementById(`area-modal-save-section`)
      .addEventListener("click", async function () {
        let area = await areaHandler.saveArea();
        await new Promise((r) => setTimeout(r, 800));
        areaHandler.parent.sectionHandler.newSection(area);
      });
  }

  mountModal(where) {
    const mountpoint = where;
    document.getElementById(mountpoint).innerHTML = /* HTML */ `
      <div class="modal-background"></div>
      <div class="modal-card" id="area-modal-card">
        <header class="modal-card-head">
          <p class="modal-card-title">
            Ajout/modification d'une circonscription
          </p>
          <button
            class="delete"
            aria-label="close"
            id="area-modal-close"
          ></button>
        </header>
        <section class="modal-card-body">
          <div class="field">
            <label>Id</label>
            <div class="control">
              <input class="input" type="number" id="area-modal-id" disabled />
            </div>
          </div>
          <div class="field">
            <label>Nom</label>
            <div class="control">
              <input class="input" type="text" id="area-modal-name" />
            </div>
          </div>
          <div class="field">
            <label>Nombre de siège</label>
            <div class="control">
              <input class="input" type="number" id="area-modal-seat-number" />
            </div>
          </div>
        </section>
        <footer class="modal-card-foot">
          <button id="area-modal-save" class="button is-success">
            Sauvegarder
          </button>
          <button id="area-modal-save-area" class="button is-success">
            Sauvegarder <br />
            (ajouter circonscription)
          </button>
          <button id="area-modal-save-section" class="button is-success">
            Sauvegarder <br />(ajouter ville)
          </button>
          <button id="area-modal-cancel" class="button">Annuler</button>
        </footer>
      </div>
    `;
  }

  async displayAreas() {
    let areaHandler = this;
    let areas = await this.updateAreas();
    const markup = areas.map((area) => this.areaTemplate(area)).join("");
    document.getElementById("area-list").innerHTML = markup;
    document.getElementById("area-new").removeAttribute("disabled");
    document.getElementById("area-title").innerHTML =
      "Circonscriptions de&nbsp;<em> " + this.election.Name + "</em>";

    areas.map((area) => {
      document
        .getElementById(`areas-area-edit-${area.ID}`)
        .addEventListener("click", function () {
          areaHandler.editArea(area);
        });
      document
        .getElementById(`areas-area-delete-${area.ID}`)
        .addEventListener("click", function () {
          new Delete(() => {
            areaHandler.deleteArea(area);
          });
        });
      document
        .getElementById(`areas-area-${area.ID}`)
        .addEventListener("click", function () {
          areaHandler.activateArea(area);
          areaHandler.parent.sectionHandler.area = area;
          areaHandler.parent.sectionHandler.displaySections();
          document.getElementById("desk-new").setAttribute("disabled", "true");
          document
            .getElementById("section-new")
            .setAttribute("disabled", "true");
        });
    });
  }

  emptyAreas() {
    this.election = null;
    document.getElementById("area-title").innerHTML = "Circonscriptions";
    document.getElementById("area-list").innerHTML =
      "Veuillez sélectionner une élection";
  }

  areaTemplate(area) {
    return /* HTML */ `<div class="card card-list">
      <div id="areas-area-${area.ID}" class="card-content">
        <div class="content">
          <nav class="level">
            <div class="level-left">
              ${area.Name} (Nombre de siège : ${area.SeatNumber})
            </div>
            <div class="level-right">
              <a
                id="areas-area-edit-${area.ID}"
                class="button is-link is-small"
                title="Modifier"
              >
                <span class="icon is-small">
                  <i class="fas fa-pen"></i>
                </span>
              </a>
              <a
                id="areas-area-delete-${area.ID}"
                class="button is-danger is-small"
                title="Supprimer"
              >
                <span class="icon is-small">
                  <i class="fas fa-times"></i>
                </span>
              </a>
            </div>
          </nav>
        </div>
      </div>
    </div>`;
  }

  async activateArea(area) {
    this.parent.sectionHandler.emptySections();
    this.parent.deskHandler.emptyDesks();
    let areas = await this.updateAreas();
    areas.forEach((area) => {
      document
        .getElementById(`areas-area-${area.ID}`)
        .classList.remove("active-card");
    });
    document
      .getElementById(`areas-area-${area.ID}`)
      .classList.add("active-card");
  }

  newArea(election) {
    this.method = "POST";
    this.election = election;
    document.getElementById("area-modal-id").value = null;
    document.getElementById("area-modal-name").value = election.Name;
    document.getElementById("area-modal-seat-number").value = null;
    Common.toggleModal("area-modal", "area-modal-card");
  }

  editArea(area) {
    this.method = "PUT";
    document.getElementById("area-modal-id").value = area.ID;
    document.getElementById("area-modal-name").value = area.Name;
    document.getElementById("area-modal-seat-number").value = area.SeatNumber;
    Common.toggleModal("area-modal", "area-modal-card");
  }

  async saveArea() {
    let area;
    if (this.method == "POST")
      document.getElementById("area-modal-id").value = null;

    try {
      const response = await fetch(
        "/api/Area/" + document.getElementById("area-modal-id").value,
        {
          method: this.method,
          headers: new Headers({
            "XSRF-Token": current_user.xsrftoken,
          }),
          body: JSON.stringify({
            ID: parseInt(document.getElementById("area-modal-id").value),
            ElectionID: this.election.ID,
            Name: document.getElementById("area-modal-name").value,
            SeatNumber: parseInt(
              document.getElementById("area-modal-seat-number").value
            ),
          }),
        }
      );
      if (response.status !== 200) {
        throw new Error(
          `Area could not be updated or created (status ${response.status})`
        );
      }
      area = await response.json();
      await this.displayAreas();
    } catch (e) {
      Messages.Show("is-warning", e.message);
      console.error(e);
    }
    Common.toggleModal("area-modal", "area-modal-card");
    this.activateArea(area);
    this.parent.sectionHandler.area = area;
    this.parent.sectionHandler.displaySections();
    return area;
  }

  async updateAreas() {
    let areaHandler = this;
    try {
      const response = await fetch("/api/Area/", {
        method: "GET",
        headers: new Headers({
          "XSRF-Token": current_user.xsrftoken,
        }),
      });
      if (response.status !== 200) {
        throw new Error(
          `Areas could not be fetched (status ${response.status})`
        );
      }
      let areas = await response.json();
      return areas.filter(function (area) {
        return area.ElectionID == areaHandler.election.ID;
      });
    } catch (e) {
      Messages.Show("is-warning", e.message);
      console.error(e);
    }
  }

  async deleteArea(area) {
    try {
      const response = await fetch("/api/Area/" + area.ID, {
        method: "delete",
        headers: new Headers({
          "XSRF-Token": current_user.xsrftoken,
        }),
      });
      if (response.status !== 200) {
        throw new Error(
          `Area could not be deleted (status ${response.status})`
        );
      }
    } catch (e) {
      Messages.Show("is-warning", e.message);
      console.error(e);
    }
    this.displayAreas();
    this.parent.sectionHandler.emptySections();
    this.parent.deskHandler.emptyDesks();
    document.getElementById("desk-new").setAttribute("disabled", "true");
    document.getElementById("section-new").setAttribute("disabled", "true");
  }

  async cloneAreas(electionCloned, electionToClone) {
    let areaHandler = this;
    await electionToClone.Areas.forEach(async (areaToClone) => {
      try {
        areaToClone = await areaHandler.getArea(areaToClone.ID);
        const response = await fetch("/api/Area/", {
          method: "POST",
          headers: new Headers({
            "XSRF-Token": current_user.xsrftoken,
          }),
          body: JSON.stringify({
            ID: null,
            ElectionID: electionCloned.ID,
            Name: areaToClone.Name,
            SeatNumber: areaToClone.SeatNumber,
          }),
        });
        if (response.status !== 200) {
          throw new Error(
            `Area could not be cloned (status ${response.status})`
          );
        }
        let areaCloned = await response.json();
        await areaHandler.parent.sectionHandler.cloneSections(
          areaCloned,
          areaToClone
        );
      } catch (e) {
        Messages.Show("is-warning", e.message);
        console.error(e);
      }
    });
  }

  async getArea(id) {
    try {
      const response = await fetch("/api/Area/" + id, {
        method: "GET",
        headers: new Headers({
          "XSRF-Token": current_user.xsrftoken,
        }),
      });
      if (response.status !== 200) {
        throw new Error(
          `Area could not be fetched (status ${response.status})`
        );
      }
      return await response.json();
    } catch (e) {
      Messages.Show("is-warning", e.message);
      console.error(e);
    }
  }
}