(function () {
  if (window.GIAComposePanel) {
    window.GIAComposePanel.initAll(document);
    return;
  }

  const core = window.GIAComposePanelCore;
  const threadModule = window.GIAComposePanelThread;
  const sendModule = window.GIAComposePanelSend;
  if (!core || !threadModule || !sendModule) {
    return;
  }

  const destroyPanelState = function (state) {
    if (!state) {
      return;
    }
    if (state.pollTimer) {
      clearInterval(state.pollTimer);
    }
    if (state.pendingCommandPoll) {
      clearInterval(state.pendingCommandPoll);
    }
    if (state.socket) {
      try {
        state.socket.close();
      } catch (_err) {
        // Ignore socket close failures.
      }
    }
    if (state.eventHandler) {
      document.body.removeEventListener("composeMessageSent", state.eventHandler);
    }
    if (state.sendResultHandler) {
      document.body.removeEventListener(
        "composeSendResult",
        state.sendResultHandler
      );
    }
    if (state.commandIdHandler) {
      document.body.removeEventListener(
        "composeSendCommandId",
        state.commandIdHandler
      );
    }
    delete window.giaComposePanels[state.panelId];
  };

  const initPanel = function (panel) {
    if (!panel) {
      return;
    }
    const panelId = String(panel.id || "").trim();
    if (!panelId) {
      return;
    }
    if (panel.dataset.composeInitialized === "1" && window.giaComposePanels[panelId]) {
      return;
    }
    destroyPanelState(window.giaComposePanels[panelId]);

    const thread = document.getElementById(panelId + "-thread");
    const form = document.getElementById(panelId + "-form");
    const textarea = document.getElementById(panelId + "-textarea");
    if (!thread || !form || !textarea) {
      return;
    }

    const state = {
      panelId: panelId,
      pollTimer: null,
      polling: false,
      socket: null,
      websocketReady: false,
      pendingCommandPoll: null,
      pendingCommandId: "",
      pendingCommandAttempts: 0,
      pendingCommandStartedAt: 0,
      pendingCommandInFlight: false,
      eventHandler: null,
      sendResultHandler: null,
      commandIdHandler: null,
    };
    window.giaComposePanels[panelId] = state;
    panel.dataset.composeInitialized = "1";

    const statusBox = document.getElementById(panelId + "-status");
    const setStatus = function (message, level) {
      if (!statusBox) {
        return;
      }
      statusBox.innerHTML = "";
      if (!message) {
        return;
      }
      statusBox.appendChild(
        core.createNode(
          "p",
          "compose-status-line is-" + String(level || "info"),
          String(message)
        )
      );
    };

    const flashCompose = function (className) {
      panel.classList.remove("is-send-success", "is-send-fail");
      void panel.offsetWidth;
      panel.classList.add(className);
      window.setTimeout(function () {
        panel.classList.remove(className);
      }, 420);
    };

    const autosize = function () {
      textarea.style.height = "auto";
      textarea.style.height = Math.min(Math.max(textarea.scrollHeight, 44), 128) + "px";
    };

    const threadController = threadModule.createController({
      contactSelect: document.getElementById(panelId + "-contact-select"),
      hiddenIdentifier: document.getElementById(panelId + "-input-identifier"),
      hiddenPerson: document.getElementById(panelId + "-input-person"),
      hiddenReplyTo: form.querySelector('input[name="reply_to_message_id"]'),
      hiddenService: document.getElementById(panelId + "-input-service"),
      metaLine: document.getElementById(panelId + "-meta-line"),
      panel: panel,
      panelId: panelId,
      platformSelect: document.getElementById(panelId + "-platform-select"),
      renderMode: String(panel.dataset.renderMode || "page"),
      replyBanner: document.getElementById(panelId + "-reply-banner"),
      replyBannerText: document.getElementById(panelId + "-reply-text"),
      replyClearBtn: document.getElementById(panelId + "-reply-clear"),
      state: state,
      textarea: textarea,
      thread: thread,
      typingNode: document.getElementById(panelId + "-typing"),
    });

    const sendController = sendModule.createController({
      armInput: form.querySelector('input[name="failsafe_arm"]'),
      autosize: autosize,
      clearReplyTarget: threadController.clearReplyTarget,
      confirmInput: form.querySelector('input[name="failsafe_confirm"]'),
      csrfToken: String(panel.dataset.csrfToken || ""),
      flashCompose: flashCompose,
      form: form,
      manualConfirm: form.querySelector(".manual-confirm"),
      panel: panel,
      panelId: panelId,
      poll: threadController.poll,
      queryParams: threadController.queryParams,
      sendButton: form.querySelector(".compose-send-btn"),
      sendCapable: String(panel.dataset.capabilitySend || "").toLowerCase() === "true",
      setStatus: setStatus,
      state: state,
      statusBox: statusBox,
      textarea: textarea,
      thread: thread,
    });

    threadController.setBeforeContextReset(sendController.resetForContextSwitch);
    autosize();
    textarea.addEventListener("input", autosize);
    threadController.init();
    sendController.init();
  };

  const initAll = function (root) {
    core.collectPanels(root).forEach(function (panel) {
      initPanel(panel);
    });
  };

  window.GIAComposePanel = {
    destroyPanel: function (panelId) {
      destroyPanelState(window.giaComposePanels[panelId]);
    },
    initAll: initAll,
    initPanel: initPanel,
  };

  document.addEventListener("DOMContentLoaded", function () {
    initAll(document);
  });
  if (document.body) {
    document.body.addEventListener("htmx:afterSwap", function (event) {
      initAll((event && event.target) || document);
    });
  }
  initAll(document);
})();
