"use strict";

import {Controller} from "@hotwired/stimulus";
import {getComponent} from "@symfony/ux-live-component";
import Mousetrap from "mousetrap";

export default class extends Controller {
  static targets = ["saveButton", "saveAndContinueButton", "saveAndProofButton", "prevSectionButton", "nextSectionButton"];
  static values = {
    unsavedChangesUrl: String,
    formDirty: Boolean,
    isCopy: Boolean,
  };

  initialize() {
    getComponent(this.element).then((component) => {
      this.component = component;
    }).catch(() => {
      // Not a live component
    });

    this.save = this.save.bind(this);
    this.saveAndContinue = this.saveAndContinue.bind(this);
    this.startSaving = this.startSaving.bind(this);
    this.stopSaving = this.stopSaving.bind(this);
    this.prevSection = this.prevSection.bind(this);
    this.nextSection = this.nextSection.bind(this);
  }

  connect() {
    this.resetDirty = this.resetDirty.bind(this);
    this.element.addEventListener("live:saved", this.resetDirty);
    this.element.addEventListener("live:render", this.stopSaving);
    this.element.addEventListener("turbo:submit-end", this.resetDirty);

    this.originalStopCallback = Mousetrap.stopCallback;
    Mousetrap.stopCallback = (e, element, combo) => {
      if (["mod+s", "mod+right", "alt+left", "alt+right"].includes(combo)) {
        return false;
      }
      if (typeof this.originalStopCallback === "function") {
        return this.originalStopCallback(e, element, combo);
      }
      return (
        element.tagName === "INPUT" ||
        element.tagName === "SELECT" ||
        element.tagName === "TEXTAREA" ||
        (element.contentEditable && element.contentEditable === "true")
      );
    };

    Mousetrap.bind(["mod+s"], (e) => {
      e.preventDefault();
      this.save();
    });
    Mousetrap.bind(['mod+right'], (e) => {
      e.preventDefault();
      this.saveAndContinue();
    });
    Mousetrap.bind(['alt+left'], (e) => {
      e.preventDefault();
      this.prevSection();
    });
    Mousetrap.bind(['alt+right'], (e) => {
      e.preventDefault();
      this.nextSection();
    });
  }

  disconnect() {
    this.element.removeEventListener("live:saved", this.resetDirty);
    this.element.removeEventListener("live:render", this.stopSaving);
    this.element.removeEventListener("turbo:submit-end", this.resetDirty);
    Mousetrap.stopCallback = this.originalStopCallback;
    Mousetrap.unbind(["mod+s"]);
    Mousetrap.unbind(['mod+right']);
    Mousetrap.unbind(['alt+left']);
    Mousetrap.unbind(['alt+right']);
  }

  startSaving() {
    this.isSaving = true;
  }

  stopSaving() {
    this.isSaving = false;
  }

  save() {
    this.isSaving = true;
    this.saveButtonTargets.forEach((btn) => btn.click());
  }

  saveAndContinue() {
    if (this.hasSaveAndContinueButtonTarget) {
      this.isSaving = true;
      this.saveAndContinueButtonTarget.click();
    } else if (this.hasSaveAndProofButtonTarget) {
      this.isSaving = true;
      this.saveAndProofButtonTarget.click();
    }
  }

  prevSection() {
    if (this.hasPrevSectionButtonTarget && !this.prevSectionButtonTarget.classList.contains('pointer-events-none')) {
      this.prevSectionButtonTarget.click();
    }
  }

  nextSection() {
    if (this.hasNextSectionButtonTarget && !this.nextSectionButtonTarget.classList.contains('pointer-events-none')) {
      this.nextSectionButtonTarget.click();
    }
  }

  formDirtyValueChanged(value) {
    [...this.saveButtonTargets, ...this.saveAndContinueButtonTargets, ...this.saveAndProofButtonTargets].forEach((btn) => {
      btn.disabled = !value;
      if (value) {
        btn.classList.remove("opacity-50");
        if (this.isCopyValue) {
          btn.classList.add("animate-pulse-ring");
        }
      } else {
        btn.classList.add("opacity-50");
        btn.classList.remove("animate-pulse-ring");
      }
    });
  }

  isDirty() {
    return this.formDirtyValue;
  }

  leavingPage(event) {
    if (this.isSaving) {
      return;
    }
    if (this.isDirty()) {
      event.preventDefault();

      if (event.type === "turbo:before-visit") {
        this.pendingVisit = event.detail.url;
        if (this.hasUnsavedChangesUrlValue) {
          fetch(this.unsavedChangesUrlValue, {
            headers: {
              Accept: "text/vnd.turbo-stream.html",
            },
          })
            .then((r) => r.text())
            .then((html) => Turbo.renderStreamMessage(html));
        } else if (
          window.confirm(
            "Sie haben Ihre Änderungen nicht gespeichert. Klicken Sie »Abbrechen«, wenn Sie Ihre Änderungen noch speichern wollen oder klicken Sie »OK«, wenn Sie Ihre Änderungen nicht speichern wollen.",
          )
        ) {
          this.formDirtyValue = false;
          Turbo.visit(this.pendingVisit);
        }
      } else if (
        !window.confirm(
          "Sie haben Ihre Änderungen nicht gespeichert. Klicken Sie »Abbrechen«, wenn Sie Ihre Änderungen noch speichern wollen oder klicken Sie »OK«, wenn Sie Ihre Änderungen nicht speichern wollen.",
        )
      ) {
        event.preventDefault();
      }
    }
  }

  continueWithoutSave(event) {
    event.preventDefault();
    this.formDirtyValue = false;
    Turbo.visit(this.pendingVisit);
  }

  closeUnsavedModal(event) {
    event.preventDefault();
    document.querySelector("el-dialog")?.hide();
  }

  resetDirty(event) {
    this.isSaving = false;
    if (event.detail.success) {
      this.formDirtyValue = false;
    }
  }
}
