"use strict";
function editDiplomacy() {
  if (customization) return;
  if (pack.states.filter(s => s.i && !s.removed).length < 2) {
    tip("There should be at least 2 states to edit the diplomacy", false, "error");
    return;
  }

  closeDialogs("#diplomacyEditor, .stable");
  if (!layerIsOn("toggleStates")) toggleStates();
  if (!layerIsOn("toggleBorders")) toggleBorders();
  if (layerIsOn("toggleProvinces")) toggleProvinces();
  if (layerIsOn("toggleCultures")) toggleCultures();
  if (layerIsOn("toggleBiomes")) toggleBiomes();
  if (layerIsOn("toggleReligions")) toggleReligions();

  const body = document.getElementById("diplomacyBodySection");
  const statuses = ["Ally", "Friendly", "Neutral", "Suspicion", "Enemy", "Unknown", "Rival", "Vassal", "Suzerain"];
  const description = [" is an ally of ", " is friendly to ", " is neutral to ", " is suspicious of ", 
    " is at war with ", " does not know about ", " is a rival of ", " is a vassal of ", " is suzerain to "];
  const colors = ["#00b300", "#d4f8aa", "#edeee8", "#eeafaa", "#e64b40", "#a9a9a9", "#ad5a1f", "#87CEFA", "#00008B"];
  refreshDiplomacyEditor();

  tip("Click on a state to see its diplomatic relations", false, "warning");
  viewbox.style("cursor", "crosshair").on("click", selectStateOnMapClick);

  if (modules.editDiplomacy) return;
  modules.editDiplomacy = true;

  $("#diplomacyEditor").dialog({
    title: "Diplomacy Editor", resizable: false, width: fitContent(), close: closeDiplomacyEditor,
    position: {my: "right top", at: "right-10 top+10", of: "svg", collision: "fit"}
  });

  // add listeners
  document.getElementById("diplomacyEditorRefresh").addEventListener("click", refreshDiplomacyEditor);
  document.getElementById("diplomacyEditStyle").addEventListener("click", () => editStyle("regions"));
  document.getElementById("diplomacyRegenerate").addEventListener("click", regenerateRelations);
  document.getElementById("diplomacyMatrix").addEventListener("click", showRelationsMatrix);
  document.getElementById("diplomacyHistory").addEventListener("click", showRelationsHistory);
  document.getElementById("diplomacyExport").addEventListener("click", downloadDiplomacyData);
  document.getElementById("diplomacySelect").addEventListener("mouseup", diplomacyChangeRelations);

  function refreshDiplomacyEditor() {
    diplomacyEditorAddLines();
    showStateRelations();
  }

  // add line for each state
  function diplomacyEditorAddLines() {
    const states = pack.states;
    const selectedLine = body.querySelector("div.Self");
    const sel = selectedLine ? +selectedLine.dataset.id : states.find(s => s.i && !s.removed).i;
    const selName = states[sel].fullName;
    diplomacySelect.style.display = "none";

    COArenderer.trigger("stateCOA"+sel, states[sel].coa);
    let lines = `<div class="states Self" data-id=${sel} data-tip="List below shows relations to ${selName}">
      <div style="width: max-content">${selName}</div>
      <svg class="coaIcon" viewBox="0 0 200 200"><use href="#stateCOA${sel}"></use></svg>
    </div>`;

    for (const s of states) {
      if (!s.i || s.removed || s.i === sel) continue;
      const relation = s.diplomacy[sel];
      const index = statuses.indexOf(relation);
      const color = colors[index];
      const tip = s.fullName + description[index] + selName;
      const tipSelect = `${tip}. Click to see relations to ${s.name}`;
      const tipChange = `${tip}. Click to change relations to ${selName}`;
      COArenderer.trigger("stateCOA"+s.i, s.coa);

      lines += `<div class="states" data-id=${s.i} data-name="${s.fullName}" data-relations="${relation}">
        <svg data-tip="${tipSelect}" class="coaIcon" viewBox="0 0 200 200"><use href="#stateCOA${s.i}"></use></svg>
        <div data-tip="${tipSelect}" style="width:12em">${s.fullName}</div>
        <svg data-tip="${tipChange}" width=".9em" height=".9em" style="margin-bottom:-1px" class="changeRelations">
          <rect x="0" y="0" width="100%" height="100%" fill="${color}" class="fillRect pointer" style="pointer-events: none"></rect>
        </svg>
        <input data-tip="${tipChange}" class="changeRelations diplomacyRelations" value="${relation}" readonly/>
      </div>`;
    }
    body.innerHTML = lines;

    // add listeners
    body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseenter", ev => stateHighlightOn(ev)));
    body.querySelectorAll("div.states").forEach(el => el.addEventListener("mouseleave", ev => stateHighlightOff(ev)));
    body.querySelectorAll("div.states").forEach(el => el.addEventListener("click", selectStateOnLineClick));
    body.querySelectorAll(".changeRelations").forEach(el => el.addEventListener("click", toggleDiplomacySelect));

    applySorting(diplomacyHeader);
    $("#diplomacyEditor").dialog();
  }

  function stateHighlightOn(event) {
    if (!layerIsOn("toggleStates")) return;
    const state = +event.target.dataset.id;
    if (customization || !state) return;
    const d = regions.select("#state"+state).attr("d");

    const path = debug.append("path").attr("class", "highlight").attr("d", d)
      .attr("fill", "none").attr("stroke", "red").attr("stroke-width", 1).attr("opacity", 1)
      .attr("filter", "url(#blur1)");

    const l = path.node().getTotalLength(), dur = (l + 5000) / 2;
    const i = d3.interpolateString("0," + l, l + "," + l);
    path.transition().duration(dur).attrTween("stroke-dasharray", function() {return t => i(t)});
  }

  function stateHighlightOff(event) {
    debug.selectAll(".highlight").each(function() {
      d3.select(this).transition().duration(1000).attr("opacity", 0).remove();
    });
  }

  function showStateRelations() {
    const selectedLine = body.querySelector("div.Self");
    const sel = selectedLine ? +selectedLine.dataset.id : pack.states.find(s => s.i && !s.removed).i;
    if (!sel) return;
    if (!layerIsOn("toggleStates")) toggleStates();

    statesBody.selectAll("path").each(function() {
      if (this.id.slice(0, 9) === "state-gap") return; // exclude state gap element
      const id = +this.id.slice(5); // state id
      const index = statuses.indexOf(pack.states[id].diplomacy[sel]); // status index
      const clr = index !== -1 ? colors[index] : "#4682b4"; // Self (bluish)
      this.setAttribute("fill", clr);
      statesBody.select("#state-gap"+id).attr("stroke", clr);
      statesHalo.select("#state-border"+id).attr("stroke", d3.color(clr).darker().hex());
    });
  }

  function selectStateOnLineClick() {
    if (this.classList.contains("Self")) return;
    body.querySelector("div.Self").classList.remove("Self");
    this.classList.add("Self");
    refreshDiplomacyEditor();
  }

  function selectStateOnMapClick() {
    const point = d3.mouse(this);
    const i = findCell(point[0], point[1]);
    const state = pack.cells.state[i];
    if (!state) return;
    const selectedLine = body.querySelector("div.Self");
    if (+selectedLine.dataset.id === state) return;

    selectedLine.classList.remove("Self");
    body.querySelector("div[data-id='"+state+"']").classList.add("Self");
    refreshDiplomacyEditor();
  }

  function toggleDiplomacySelect(event) {
    event.stopPropagation();
    const select = document.getElementById("diplomacySelect");
    const show = select.style.display === "none";
    if (!show) {select.style.display = "none"; return;}
    select.style.display = "block";
    const input = event.target.closest("div").querySelector("input");
    select.style.left = input.getBoundingClientRect().left + "px";
    select.style.top = input.getBoundingClientRect().bottom + "px";
    body.dataset.state = event.target.closest("div.states").dataset.id;
  }

  function diplomacyChangeRelations(event) {
    event.stopPropagation();
    diplomacySelect.style.display = "none";
    const subject = +body.dataset.state;
    const rel = event.target.innerHTML;

    const states = pack.states, chronicle = states[0].diplomacy;
    const selectedLine = body.querySelector("div.Self");
    const object = selectedLine ? +selectedLine.dataset.id : states.find(s => s.i && !s.removed).i;
    if (!object) return;
    const objectName = states[object].name; // object of relations change
    const subjectName = states[subject].name; // subject of relations change - actor

    const oldRel = states[subject].diplomacy[object];
    if (rel === oldRel) return;
    states[subject].diplomacy[object] = rel;
    states[object].diplomacy[subject] = rel === "Vassal" ? "Suzerain" : rel === "Suzerain" ? "Vassal" : rel;

    // update relation history
    const change = () => [`Relations change`, `${subjectName}-${getAdjective(objectName)} relations changed to ${rel.toLowerCase()}`];
    const ally = () => [`Defence pact`, `${subjectName} entered into defensive pact with ${objectName}`];
    const vassal = () => [`Vassalization`, `${subjectName} became a vassal of ${objectName}`];
    const suzerain = () => [`Vassalization`, `${subjectName} vassalized ${objectName}`];
    const rival = () => [`Rivalization`, `${subjectName} and ${objectName} became rivals`];
    const unknown = () => [`Relations severance`, `${subjectName} recalled their ambassadors and wiped all the records about ${objectName}`];
    const war = () => [`War declaration`, `${subjectName} declared a war on its enemy ${objectName}`];
    const peace = () => {
      const treaty = `${subjectName} and ${objectName} agreed to cease fire and signed a peace treaty`;
      const changed = rel === "Ally" ? ally()
        : rel === "Vassal" ? vassal()
        : rel === "Suzerain" ? suzerain()
        : rel === "Unknown" ? unknown()
        : change();
      return [`War termination`, treaty, changed[1]];
    }

    if (oldRel === "Enemy") chronicle.push(peace()); else
    if (rel === "Enemy") chronicle.push(war()); else
    if (rel === "Vassal") chronicle.push(vassal()); else
    if (rel === "Suzerain") chronicle.push(suzerain()); else
    if (rel === "Ally") chronicle.push(ally()); else
    if (rel === "Unknown") chronicle.push(unknown()); else
    if (rel === "Rival") chronicle.push(rival()); else
    chronicle.push(change());

    refreshDiplomacyEditor();
  }

  function regenerateRelations() {
    BurgsAndStates.generateDiplomacy();
    refreshDiplomacyEditor();
  }

  function showRelationsHistory() {
    const chronicle = pack.states[0].diplomacy;
    if (!chronicle.length) {tip("Relations history is blank", false, "error"); return;}

    let message = `<div autocorrect="off" spellcheck="false">`;
    chronicle.forEach((e, d) => {
      message += `<div>`;
      e.forEach((l, i) => message += `<div contenteditable="true" data-id="${d}-${i}"${i ? "" : " style='font-weight:bold'"}>${l}</div>`);
      message += `&#8205;</div>`;
    });
    alertMessage.innerHTML = message + `</div><i id="info-line">Type to edit. Press Enter to add a new line, empty the element to remove it</i>`;
    alertMessage.querySelectorAll("div[contenteditable='true']").forEach(el => el.addEventListener("input", changeReliationsHistory));

    $("#alert").dialog({title: "Relations history", position: {my: "center", at: "center", of: "svg"},
      buttons: {
        Save: function() {
          const data = this.querySelector("div").innerText.split("\n").join("\r\n");
          const name = getFileName("Relations history") + ".txt";
          downloadFile(data, name);
        },
        Clear: function() {pack.states[0].diplomacy = []; $(this).dialog("close");},
        Close: function() {$(this).dialog("close");}
      }
    });
  }

  function changeReliationsHistory() {
    const i = this.dataset.id.split("-");
    const group = pack.states[0].diplomacy[i[0]];
    if (this.innerHTML === "") {
      group.splice(i[1], 1);
      this.remove();
    } else group[i[1]] = this.innerHTML;
  }

  function showRelationsMatrix() {
    const states = pack.states.filter(s => s.i && !s.removed);
    const valid = states.map(s => s.i);

    let message = `<table class="matrix-table"><tr><th data-tip='&#8205;'></th>`;
    message += states.map(s => `<th data-tip='See relations to ${s.fullName}'>${s.name}</th>`).join("") + `</tr>`; // headers
    states.forEach(s => {
      message += `<tr><th data-tip='See relations of ${s.fullName}'>${s.name}</th>` + s.diplomacy
        .filter((v, i) => valid.includes(i)).map((r, i) => {
          const desc = description[statuses.indexOf(r)];
          const tip = desc ? s.fullName + desc + pack.states[valid[i]].fullName : '&#8205;';
          return `<td data-tip='${tip}' class='${r}'>${r}</td>`
        }).join("") + "</tr>";
    });
    message += `</table>`;
    alertMessage.innerHTML = message;
    
    $("#alert").dialog({title: "Relations matrix", width: fitContent(), position: {my: "center", at: "center", of: "svg"}, buttons: {}});
  }

  function downloadDiplomacyData() {
    const states = pack.states.filter(s => s.i && !s.removed);
    const valid = states.map(s => s.i);

    let data = "," + states.map(s => s.name).join(",") + "\n"; // headers
    states.forEach(s => {
      const rels = s.diplomacy.filter((v, i) => valid.includes(i));
      data += s.name + "," + rels.join(",") + "\n";
    });

    const name = getFileName("Relations") + ".csv";
    downloadFile(data, name);
  }

  function closeDiplomacyEditor() {
    restoreDefaultEvents();
    clearMainTip();
    const selected = body.querySelector("div.Self");
    if (selected) selected.classList.remove("Self");
    if (layerIsOn("toggleStates")) drawStates(); else toggleStates();
    debug.selectAll(".highlight").remove();
  }
}
