// Imports
import * as Auth from "/services/auth/auth.js";
import * as results from "/services/election/calculate-election-generic.js";
import * as PartyModel from "/services/model/party-model.js";
import * as Scroller from "/services/common/scroller.js";

export async function mount(where, round) {
  const resultComponent = new ResultComponent(round);
  await resultComponent.mount(where);
  await resultComponent.calculateResults();
  resultComponent.displayResults();
}

class ResultComponent {
  constructor(round) {
    this.round = round;
    this.PartyModel = PartyModel.getPartyModel();
  }

  async mount(where) {
    this.PartyModel.current_user = await Auth.GetUser();
    const mountpoint = where;
    document.getElementById(mountpoint).innerHTML = /* HTML */ `
      <div class="tabs is-boxed is-toggle is-fullwidth">
        <ul>
          <li id="areas" class="is-active">
            <a>
              <span>Circonscriptions</span>
            </a>
          </li>
          <li id="sections">
            <a>
              <span>Villes</span>
            </a>
          </li>
        </ul>
      </div>
      <div class="control filter">
        <label class="radio">
          <input type="radio" name="filter" value="partial" checked />
          Partiel
        </label>
        <label class="radio">
          <input type="radio" name="filter" value="completed" />
          Complété
        </label>
        <label class="radio">
          <input type="radio" name="filter" value="validated" />
          Validé
        </label>
      </div>
      <div class="columns">
        <div class="column is-half">
          <div id="map-section" class="card-no-hover">
            <header class="card-header">
              <p class="card-header-title">
                Carte
              </p>
              <button id="zoom-map" class="button is-success">
                <span class="icon is-small">
                  <i class="fas fa-search"></i>
                </span>
              </button>
            </header>
            <div class="card-content">
              <div id="round-list" class="content">
                La carte du tour
              </div>
            </div>
          </div>
        </div>
        <div class="column">
          <div id="news-flow-section" class="card-no-hover">
            <header class="card-header">
              <p class="card-header-title">
                Actualités
              </p>
              <button id="zoom-news-flow" class="button is-success">
                <span class="icon is-small">
                  <i class="fas fa-search"></i>
                </span>
              </button>
            </header>
            <div class="card-content">
              <div id="news-flow" class="content">
                Flux d'actualité
              </div>
            </div>
          </div>
          <div id="results-section" class="card-no-hover" ">
          <header class="card-header">
            <p class="card-header-title">
              Résultats
            </p>
            <button id="zoom-results" class="button is-success">
              <span class="icon is-small">
                <i class="fas fa-search"></i>
              </span>
            </button>
          </header>
          <div class="card-content">
            <div id="detailed-results" class="content">
              <div class="control select">
                <select id="select-areas" class="input"></select>
              </div>
              <div class="control select">
                <select id="select-sections" class="input"></select>
              </div>
              <div id="zone-results"></div>
              <div id="zone-detaileds-results" style="display:none"></div>
            </div>
          </div>
        </div>
      </div>
    `;
    this.calculator = await results.mountCalculator(this.round);
    this.handleDom();
    document.getElementById("areas").click();
  }

  resultFlowTemplate(zone) {
    return /* HTML */ `<div class="card-list card-no-hover">
      <div class="card-content">
        <div id="flow-content-${zone.ID}" class="content">
          <h5 class="title is-5">${zone.Name}</h5>
        </div>
      </div>
    </div>`;
  }

  progressBarTemplate(candidateList, color) {
    return /* HTML */ `<div class="progressBar">
      <div
        class="progressBarValue"
        style="background-color : ${color}; width : ${candidateList.Percentage}%"
      >
        ${candidateList.Name +
        " (" +
        (candidateList.VoiceNumber != null
          ? candidateList.VoiceNumber + " votes soit : "
          : "") +
        candidateList.Percentage +
        "%)"}
      </div>
    </div>`;
  }

  showWarningResults(text) {
    return /* HTML */ `<br />
      <article class="message is-warning">
        <div class="message-header">
          <p>Warning</p>
        </div>
        <div class="message-body">
          ${text}
        </div>
      </article>`;
  }

  handleDom() {
    let resultHandler = this;
    document.getElementById("areas").addEventListener("click", function () {
      resultHandler.zone = "areas";
      resultHandler.calculateResults();
      resultHandler.displayResults();
      document.getElementById("sections").setAttribute("class", "");
      document.getElementById("areas").setAttribute("class", "is-active");
    });
    document.getElementById("sections").addEventListener("click", function () {
      resultHandler.zone = "sections";
      resultHandler.calculateResults();
      resultHandler.displayResults();
      document.getElementById("areas").setAttribute("class", "");
      document.getElementById("sections").setAttribute("class", "is-active");
    });

    document.getElementById("zoom-map").addEventListener("click", function () {
      resultHandler.zoomMap();
    });
    document
      .getElementById("zoom-news-flow")
      .addEventListener("click", function () {
        resultHandler.zoomNewsFlow();
      });
    document
      .getElementById("zoom-results")
      .addEventListener("click", function () {
        resultHandler.zoomResults();
      });

    let radioButtons = document.getElementsByName("filter");
    for (var i = 0; i < radioButtons.length; i++) {
      radioButtons[i].addEventListener("click", async (e) => {
        await this.calculateResults();
        this.displayResults();
      });
    }

    document.addEventListener(
      "input",
      function __listener(event) {
        if (event.target.id == "select-areas") {
          if (event.target.value != 0) {
            let area = resultHandler.results.areasResults.find(
              (area) => area.ID == event.target.value
            );

            if (resultHandler.zone === "areas")
              resultHandler.displayZoneResults(area);
            else if (resultHandler.zone === "sections") {
              resultHandler.refreshSections(area);
              resultHandler.displayZoneResults(area.Sections[0]);
            }
          }
        } else if (event.target.id == "select-sections") {
          let area = resultHandler.results.areasResults.find(
            (area) => area.ID == document.getElementById("select-areas").value
          );
          let section = area.Sections.find(
            (section) => section.ID == event.target.value
          );
          resultHandler.displayZoneResults(section);
        }
      },
      false
    );
  }

  zoomMap() {
    let resultHandler = this;
    document.getElementById("map-section").parentElement.className =
      "column is-full";
    document.getElementById("zoom-map").addEventListener("click", function () {
      resultHandler.unZoom();
    });
  }

  zoomNewsFlow() {
    let resultHandler = this;
    document.getElementById("news-flow-section").parentElement.className =
      "column is-full";
    document.getElementById("news-flow-section").style.height = "70vh";
    document.getElementById("map-section").parentElement.className = "column";
    document.getElementById("map-section").parentElement.style.display = "none";
    document.getElementById("results-section").style.display = "none";
    document
      .getElementById("zoom-news-flow")
      .addEventListener("click", function () {
        resultHandler.unZoom();
      });
  }

  zoomResults() {
    let resultHandler = this;
    document.getElementById("results-section").parentElement.className =
      "column is-full";
    document.getElementById("results-section").style.height = "70vh";
    document.getElementById("map-section").parentElement.className = "column";
    document.getElementById("map-section").parentElement.style.display = "none";
    document.getElementById("news-flow-section").style.display = "none";
    document
      .getElementById("zoom-results")
      .addEventListener("click", function () {
        resultHandler.unZoom();
      });
    document.getElementById("zone-detaileds-results").style.display = "block";
  }

  unZoom() {
    document.getElementById("map-section").parentElement.className =
      "column is-half";
    document.getElementById("news-flow-section").style.height = "45vh";
    document.getElementById("results-section").style.height = "25vh";
    document.getElementById("news-flow-section").parentElement.className =
      "column is-half";
    document.getElementById("map-section").parentElement.style.display =
      "block";
    document.getElementById("results-section").style.display = "block";
    document.getElementById("news-flow-section").style.display = "block";
    document.getElementById("zone-detaileds-results").style.display = "none";

    this.handleDom();
  }

  async calculateResults() {
    this.filter = document.querySelector('input[name="filter"]:checked').value;
    this.results = await this.calculator.calculateResults(this.filter);
  }

  displayResults() {
    document.getElementById("news-flow").innerHTML = "";
    if (this.zone === "areas") {
      this.displayFlowAreas();
      this.displayAreasResults();
    } else if (this.zone === "sections") {
      this.displayFlowSections();
      this.displaySectionsResults();
    }
    Scroller.scrollInit("news-flow");
  }

  async displayFlowAreas() {
    this.results.areasResults.sort(function (a, b) {
      return b.DateCompletion - a.DateCompletion;
    });
    for (let j in this.results.areasResults) {
      let area = this.results.areasResults[j];
      if (area.status === this.filter) {
        document.getElementById(
          "news-flow"
        ).innerHTML += this.resultFlowTemplate(area);

        for (let i in area.candidateLists) {
          let party = await this.PartyModel.getParty(
            area.candidateLists[i].PartyID
          );

          document.getElementById(
            "flow-content-" + area.ID
          ).innerHTML += await this.progressBarTemplate(
            area.candidateLists[i],
            party.Color
          );
        }
      }
    }
  }

  async displayFlowSections() {
    let sections = [];
    this.results.areasResults.forEach((area) => {
      sections = sections.concat(area.Sections);
    });
    sections.sort(function (a, b) {
      return b.DateCompletion - a.DateCompletion;
    });

    for (let j in sections) {
      let section = sections[j];
      if (section.status === this.filter) {
        document.getElementById(
          "news-flow"
        ).innerHTML += this.resultFlowTemplate(section);

        for (let i in section.candidateLists) {
          let party = await this.PartyModel.getParty(
            section.candidateLists[i].PartyID
          );

          document.getElementById(
            "flow-content-" + section.ID
          ).innerHTML += await this.progressBarTemplate(
            section.candidateLists[i],
            party.Color
          );
        }
      }
    }
  }

  displayRoundResults() {
    document.getElementById(
      "detailed-results"
    ).innerHTML = `<h5 class="title is-5">Résultats détaillés du tour</h5>`;
    for (let i in this.results.roundResults) {
      document.getElementById(
        "detailed-results"
      ).innerHTML += this.progressBarTemplate(
        this.results.roundResults[i],
        this.results.roundResults[i].Color
      );
    }
  }

  displayAreasResults() {
    let selectAreas = document.getElementById("select-areas");
    document.getElementById("select-sections").parentNode.style.display =
      "none";

    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
      selectAreas.remove(i);
    }

    this.results.areasResults.forEach((area) => {
      let el = document.createElement("option");
      el.textContent = area.Name;
      el.value = area.ID;
      selectAreas.appendChild(el);
    });

    this.displayZoneResults(this.results.areasResults[0]);
  }

  displaySectionsResults() {
    let selectAreas = document.getElementById("select-areas");
    document.getElementById("select-sections").parentNode.style.display =
      "block";

    for (let i = selectAreas.options.length - 1; i >= 0; i--) {
      selectAreas.remove(i);
    }

    this.results.areasResults.forEach((area) => {
      let el = document.createElement("option");
      el.textContent = area.Name;
      el.value = area.ID;
      selectAreas.appendChild(el);
    });

    this.refreshSections(this.results.areasResults[0]);

    this.displayZoneResults(this.results.areasResults[0].Sections[0]);
  }

  async displayZoneResults(zone) {
    if (zone.status !== this.filter) {
      console.log(zone);
      if (zone.status == "no_results") {
        document.getElementById(
          "zone-results"
        ).innerHTML = this.showWarningResults(
          "Aucun résultats n'ont étaient saisis sur cette zone"
        );
      } else if (zone.status == "incompleted") {
        document.getElementById(
          "zone-results"
        ).innerHTML = this.showWarningResults(
          "Les résultats pour cette zone ne sont pas complets"
        );
      } else if (zone.status == "not validated") {
        document.getElementById(
          "zone-results"
        ).innerHTML = this.showWarningResults(
          "Les résultats pour cette zone n'ont pas étaient validés"
        );
      }
      document.getElementById("zone-detaileds-results").innerHTML = "";
    } else {
      document.getElementById("zone-results").innerHTML =
        '<br/><h5 class="title is-5">Résultats</h5>';
      for (let i in zone.candidateLists) {
        let party = await this.PartyModel.getParty(
          zone.candidateLists[i].PartyID
        );
        document.getElementById(
          "zone-results"
        ).innerHTML += this.progressBarTemplate(
          zone.candidateLists[i],
          party.Color
        );
      }
      this.displayZoneDetailedResults(zone);
    }
  }

  displayZoneDetailedResults(zone) {
    document.getElementById("zone-detaileds-results").innerHTML =
      '<br/><h5 class="title is-5">Statistiques</h5>';

    if (this.filter === "partial")
      document.getElementById(
        "zone-detaileds-results"
      ).innerHTML += this.progressBarTemplate(
        {
          Name: "Pourcentage de saisie",
          Percentage: zone.stats.PercentageConsiderated,
          VoiceNumber: null,
        },
        "grey"
      );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.progressBarTemplate(
      {
        Name: "Abstention",
        Percentage: zone.stats.Abstention,
        VoiceNumber: null,
      },
      "grey"
    );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.progressBarTemplate(
      {
        Name: "Votes blancs",
        Percentage: zone.stats.BlankPercentage,
        VoiceNumber: zone.stats.BlankVoiceNumber,
      },
      "grey"
    );
    document.getElementById(
      "zone-detaileds-results"
    ).innerHTML += this.progressBarTemplate(
      {
        Name: "Votes nuls",
        Percentage: zone.stats.NullVotePercentage,
        VoiceNumber: zone.stats.NullVoteVoiceNumber,
      },
      "grey"
    );
  }

  refreshSections(area) {
    let selectSections = document.getElementById("select-sections");
    selectSections.parentNode.style.display = "block";
    for (let i = selectSections.options.length - 1; i >= 0; i--) {
      selectSections.remove(i);
    }
    for (let i in area.Sections) {
      let el = document.createElement("option");
      el.textContent = area.Sections[i].Name;
      el.value = area.Sections[i].ID;
      selectSections.appendChild(el);
    }
  }
}