const STYLE_ID = "st-bme-notice-style";
const HOST_ID = "st-bme-notice-host";

function resolveNoticeDocument() {
  const runtime = globalThis;
  const chatDocument = runtime?.SillyTavern?.Chat?.document;
  if (chatDocument && typeof chatDocument.createElement === "function") {
    return chatDocument;
  }

  try {
    return (window.parent && window.parent !== window ? window.parent : window).document;
  } catch {
    return document;
  }
}

function ensureStyle(doc) {
  if (doc.getElementById(STYLE_ID)) return;

  const style = doc.createElement("style");
  style.id = STYLE_ID;
  style.textContent = `
    #${HOST_ID} {
      position: fixed;
      top: 14px;
      right: 14px;
      z-index: 12020;
      width: min(400px, calc(100vw - 28px));
      display: flex;
      flex-direction: column;
      gap: 10px;
      pointer-events: none;
    }

    .st-bme-notice {
      --st-bme-accent: #73b8ff;
      pointer-events: auto;
      position: relative;
      display: grid;
      grid-template-columns: auto 1fr auto;
      gap: 12px;
      align-items: start;
      padding: 12px 12px 12px 10px;
      border-radius: 14px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background:
        radial-gradient(circle at 10% -10%, rgba(115, 184, 255, 0.2), transparent 52%),
        linear-gradient(145deg, rgba(27, 37, 54, 0.95), rgba(12, 18, 29, 0.93));
      box-shadow:
        0 14px 34px rgba(4, 10, 17, 0.46),
        inset 0 0 0 1px rgba(255, 255, 255, 0.04);
      color: #edf3fb;
      overflow: hidden;
      transform: translateY(-8px) scale(0.985);
      opacity: 0;
      animation: stBmeNoticeIn 190ms ease forwards;
      font-family: "Noto Sans SC", "PingFang SC", "Microsoft YaHei UI", sans-serif;
      backdrop-filter: blur(10px) saturate(125%);
      -webkit-backdrop-filter: blur(10px) saturate(125%);
      transition:
        grid-template-columns 260ms cubic-bezier(0.22, 1, 0.36, 1),
        padding 260ms cubic-bezier(0.22, 1, 0.36, 1),
        border-radius 260ms cubic-bezier(0.22, 1, 0.36, 1),
        width 260ms cubic-bezier(0.22, 1, 0.36, 1);
    }

    .st-bme-notice[data-layout="compact"] {
      display: flex;
      align-items: center;
      gap: 10px;
      max-width: min(400px, calc(100vw - 28px));
      align-self: flex-end;
      padding: 10px;
    }

    .st-bme-notice__content {
      min-width: 0;
      flex: 1 1 0%;
      transition: max-width 280ms cubic-bezier(0.22, 1, 0.36, 1),
                 opacity 220ms ease;
    }

    .st-bme-notice[data-layout="normal"] .st-bme-notice__content {
      overflow: hidden;
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__content {
      display: flex;
      align-items: center;
      min-width: 0;
      overflow: hidden;
    }

    .st-bme-notice__title {
      margin: 0;
      font-size: 17px;
      line-height: 1.18;
      font-weight: 800;
      letter-spacing: 0.01em;
      color: #f0f6ff;
      transition: font-size 260ms ease;
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__title {
      font-size: 16px;
      line-height: 1.2;
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      flex: 0 1 auto;
      min-width: 0;
    }

    .st-bme-notice__message {
      margin: 4px 0 0;
      font-size: 14px;
      line-height: 1.38;
      color: rgba(240, 246, 255, 0.86);
      white-space: pre-wrap;
      word-break: break-word;
      overflow: hidden;
      transition: max-height 280ms cubic-bezier(0.22, 1, 0.36, 1),
                 opacity 220ms ease,
                 margin 260ms ease;
    }

    .st-bme-notice[data-layout="normal"] .st-bme-notice__message {
      max-height: 200px;
      opacity: 1;
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__message {
      max-height: 0;
      opacity: 0;
      margin-top: 0;
      display: none;
    }

    .st-bme-notice::after {
      content: "";
      position: absolute;
      inset: 0;
      border-left: 3px solid var(--st-bme-accent);
      border-radius: 14px;
      pointer-events: none;
      opacity: 0.9;
    }

    .st-bme-notice--out {
      animation: stBmeNoticeOut 160ms ease forwards;
    }

    .st-bme-notice__icon {
      width: 30px;
      height: 30px;
      border-radius: 10px;
      display: inline-flex;
      align-items: center;
      justify-content: center;
      font-size: 15px;
      font-weight: 800;
      color: #f4f8ff;
      background: rgba(255, 255, 255, 0.08);
      border: 1px solid rgba(255, 255, 255, 0.14);
      box-shadow: inset 0 1px 1px rgba(255, 255, 255, 0.16);
      flex-shrink: 0;
    }

    .st-bme-notice[data-busy="true"] .st-bme-notice__icon {
      animation: stBmeNoticeBusy 900ms linear infinite;
    }

    .st-bme-notice__message--marquee {
      white-space: nowrap;
      overflow: hidden;
      text-overflow: ellipsis;
      font-family: "Cascadia Code", "Fira Code", "JetBrains Mono", monospace;
      font-size: 12.5px;
      color: rgba(240, 246, 255, 0.72);
      mask-image: linear-gradient(90deg, transparent 0%, black 6%, black 88%, transparent 100%);
      -webkit-mask-image: linear-gradient(90deg, transparent 0%, black 6%, black 88%, transparent 100%);
    }

    .st-bme-notice__action {
      min-height: 30px;
      padding: 0 12px;
      border-radius: 999px;
      border: 1px solid rgba(255, 255, 255, 0.16);
      background: rgba(255, 255, 255, 0.08);
      color: #eef4ff;
      font-size: 13px;
      font-weight: 700;
      cursor: pointer;
      transition: background 140ms ease, border-color 140ms ease, transform 140ms ease;
    }

    .st-bme-notice__action:hover,
    .st-bme-notice__action:focus-visible {
      background: rgba(255, 255, 255, 0.16);
      border-color: rgba(255, 255, 255, 0.24);
      transform: translateY(-1px);
      outline: none;
    }

    .st-bme-notice__action[data-kind="danger"] {
      background: rgba(245, 123, 143, 0.16);
      border-color: rgba(245, 123, 143, 0.42);
      color: #ffd9df;
    }

    .st-bme-notice__close {
      width: 22px;
      height: 22px;
      border: none;
      border-radius: 7px;
      background: rgba(255, 255, 255, 0.08);
      color: #d7e0ec;
      font-size: 15px;
      line-height: 1;
      cursor: pointer;
      transition: background 140ms ease;
      flex-shrink: 0;
    }

    .st-bme-notice__close:hover,
    .st-bme-notice__close:focus-visible {
      background: rgba(255, 255, 255, 0.2);
      outline: none;
    }

    .st-bme-notice__toggle-hint {
      position: absolute;
      bottom: 6px;
      right: 32px;
      font-size: 10px;
      color: rgba(240, 246, 255, 0.35);
      pointer-events: none;
      transition: opacity 180ms ease;
      opacity: 0;
    }

    .st-bme-notice:hover .st-bme-notice__toggle-hint {
      opacity: 1;
    }

    .st-bme-notice[data-layout="normal"] .st-bme-notice__toggle-hint::after {
      content: "▸ 简洁";
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__toggle-hint::after {
      content: "▸ 详细";
    }

    .st-bme-notice--switching {
      pointer-events: none;
    }

    .st-bme-notice--switching .st-bme-notice__content {
      opacity: 0;
    }

    .st-bme-notice__actions {
      display: flex;
      gap: 8px;
      margin-top: 10px;
      overflow: hidden;
      transition: max-height 260ms cubic-bezier(0.22, 1, 0.36, 1),
                 opacity 220ms ease,
                 margin 260ms ease;
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__actions {
      max-height: 0;
      opacity: 0;
      margin-top: 0;
      overflow: hidden;
      display: none;
    }

    .st-bme-notice[data-layout="normal"] .st-bme-notice__actions {
      max-height: 60px;
      opacity: 1;
    }

    .st-bme-notice[data-layout="compact"] .st-bme-notice__progress {
      display: none;
    }

    .st-bme-notice__progress {
      position: absolute;
      left: 0;
      bottom: 0;
      height: 2px;
      width: 100%;
      background: linear-gradient(90deg, var(--st-bme-accent), rgba(255, 255, 255, 0.24));
      transform-origin: left center;
      animation: stBmeNoticeProgress linear forwards;
    }

    .st-bme-notice[data-level="success"] {
      --st-bme-accent: #65d39c;
    }

    .st-bme-notice[data-level="error"] {
      --st-bme-accent: #f57b8f;
    }

    .st-bme-notice[data-level="warning"] {
      --st-bme-accent: #eab96f;
    }

    @keyframes stBmeNoticeIn {
      to {
        transform: translateY(0) scale(1);
        opacity: 1;
      }
    }

    @keyframes stBmeNoticeOut {
      to {
        transform: translateY(-6px) scale(0.98);
        opacity: 0;
      }
    }

    @keyframes stBmeNoticeProgress {
      from {
        transform: scaleX(1);
      }
      to {
        transform: scaleX(0);
      }
    }

    @keyframes stBmeNoticeBusy {
      from {
        transform: rotate(0deg);
      }
      to {
        transform: rotate(360deg);
      }
    }

    @media (max-width: 900px) {
      #${HOST_ID} {
        top: 8px;
        right: 8px;
        width: calc(100vw - 16px);
      }
    }

    @media (prefers-reduced-motion: reduce) {
      .st-bme-notice,
      .st-bme-notice--out,
      .st-bme-notice__progress {
        animation-duration: 1ms !important;
      }
    }
  `;

  (doc.head || doc.documentElement).appendChild(style);
}

function ensureHost(doc) {
  let host = doc.getElementById(HOST_ID);
  if (host) return host;

  host = doc.createElement("div");
  host.id = HOST_ID;
  host.setAttribute("aria-live", "polite");
  host.setAttribute("aria-atomic", "false");
  (doc.body || doc.documentElement).appendChild(host);
  return host;
}

function getIcon(level) {
  switch (level) {
    case "success":
      return "✓";
    case "error":
      return "!";
    case "warning":
      return "△";
    default:
      return "i";
  }
}

function applyNoticeState(item, input, progress) {
  const level = input.level || "info";
  const displayMode = input.displayMode === "compact" ? "compact" : "normal";
  const isCompact = displayMode === "compact";
  item.dataset.level = level;
  item.dataset.busy = input.busy ? "true" : "false";
  item.dataset.layout = displayMode;

  const icon = item.querySelector(".st-bme-notice__icon");
  if (icon) {
    icon.textContent = input.busy ? "◌" : getIcon(level);
  }

  const title = item.querySelector(".st-bme-notice__title");
  if (title) {
    title.textContent = input.title || "ST-BME";
  }

  const message = item.querySelector(".st-bme-notice__message");
  if (message) {
    message.textContent = input.message || "";
    message.hidden = !String(input.message || "").trim();
    if (input.marquee) {
      message.classList.add("st-bme-notice__message--marquee");
    } else {
      message.classList.remove("st-bme-notice__message--marquee");
    }
  }

  const actionWrap = item.querySelector(".st-bme-notice__actions");
  const actionButton = item.querySelector(".st-bme-notice__action");
  if (actionWrap && actionButton) {
    if (input.action?.label) {
      actionButton.style.display = "";
      actionButton.textContent = input.action.label;
      actionButton.dataset.kind = input.action.kind || "neutral";
    } else {
      actionButton.style.display = "none";
      actionButton.textContent = "";
      actionButton.dataset.kind = "neutral";
    }
  }

  if (input.persist || isCompact) {
    progress.style.display = "none";
    progress.style.animationDuration = "";
  } else {
    const duration = Math.max(1400, input.duration_ms || 3200);
    progress.style.display = "";
    progress.style.animationDuration = `${duration}ms`;
  }
}

export function showManagedBmeNotice(input) {
  const doc = resolveNoticeDocument();
  ensureStyle(doc);
  const host = ensureHost(doc);

  const item = doc.createElement("article");
  item.className = "st-bme-notice";

  const icon = doc.createElement("span");
  icon.className = "st-bme-notice__icon";

  const content = doc.createElement("div");
  content.className = "st-bme-notice__content";

  const title = doc.createElement("h4");
  title.className = "st-bme-notice__title";

  const message = doc.createElement("p");
  message.className = "st-bme-notice__message";

  const actions = doc.createElement("div");
  actions.className = "st-bme-notice__actions";

  const actionButton = doc.createElement("button");
  actionButton.className = "st-bme-notice__action";
  actionButton.type = "button";
  actionButton.style.display = "none";

  const closeButton = doc.createElement("button");
  closeButton.className = "st-bme-notice__close";
  closeButton.type = "button";
  closeButton.setAttribute("aria-label", "关闭提示");
  closeButton.textContent = "×";

  const progress = doc.createElement("div");
  progress.className = "st-bme-notice__progress";

  const toggleHint = doc.createElement("span");
  toggleHint.className = "st-bme-notice__toggle-hint";

  content.appendChild(title);
  content.appendChild(message);
  actions.appendChild(actionButton);
  content.appendChild(actions);
  item.appendChild(icon);
  item.appendChild(content);
  item.appendChild(closeButton);
  item.appendChild(toggleHint);
  item.appendChild(progress);

  let currentInput = input || {};
  let closed = false;
  let closeTimer = null;
  let switching = false;

  const clearCloseTimer = () => {
    if (!closeTimer) return;
    clearTimeout(closeTimer);
    closeTimer = null;
  };

  const close = (reason = "programmatic") => {
    if (closed) return;
    clearCloseTimer();
    closed = true;
    try {
      currentInput.onDismiss?.({ reason });
    } catch (error) {
      console.debug?.("[ST-BME] notice dismiss callback failed", error);
    }
    item.classList.add("st-bme-notice--out");
    setTimeout(() => {
      item.remove();
      if (!host.childElementCount) {
        host.remove();
      }
    }, 170);
  };

  const scheduleAutoClose = (nextInput) => {
    clearCloseTimer();
    if (nextInput.persist) return;
    const duration = Math.max(1400, nextInput.duration_ms || 3200);
    closeTimer = setTimeout(() => close("auto"), duration);
  };

  const update = (nextInput) => {
    if (closed) return;
    currentInput = nextInput || {};
    applyNoticeState(item, currentInput, progress);
    scheduleAutoClose(currentInput);
  };

  applyNoticeState(item, currentInput, progress);
  scheduleAutoClose(currentInput);

  actionButton.addEventListener("click", (event) => {
    event.preventDefault();
    event.stopPropagation();
    currentInput.action?.onClick?.();
  });
  closeButton.addEventListener("click", (event) => {
    event.preventDefault();
    event.stopPropagation();
    close("user");
  });

  content.addEventListener("click", (event) => {
    if (closed || switching) return;
    if (event.target === actionButton || event.target === closeButton) return;
    if (actionButton.contains(event.target) || closeButton.contains(event.target)) return;

    switching = true;
    item.classList.add("st-bme-notice--switching");

    const currentLayout = item.dataset.layout || "normal";
    const nextLayout = currentLayout === "compact" ? "normal" : "compact";

    setTimeout(() => {
      item.dataset.layout = nextLayout;
      currentInput.displayMode = nextLayout;

      if (nextLayout === "normal") {
        const msgEl = item.querySelector(".st-bme-notice__message");
        if (msgEl) msgEl.hidden = !String(currentInput.message || "").trim();
      }

      if (nextLayout === "normal" && !currentInput.persist) {
        clearCloseTimer();
        const duration = Math.max(1400, currentInput.duration_ms || 3200);
        closeTimer = setTimeout(() => close("auto"), duration);
        const progressEl = item.querySelector(".st-bme-notice__progress");
        if (progressEl) {
          progressEl.style.display = "";
          progressEl.style.animationDuration = `${duration}ms`;
          progressEl.style.animation = "none";
          void progressEl.offsetHeight;
          progressEl.style.animation = "";
        }
      }

      setTimeout(() => {
        item.classList.remove("st-bme-notice--switching");
        switching = false;
      }, 60);
    }, 180);
  });

  host.appendChild(item);

  return {
    update,
    dismiss: close,
    isClosed: () => closed,
  };
}

export function showBmeNotice(input) {
  return showManagedBmeNotice(input);
}
