import { escapeHtml } from "../utils.js";

export function renderMessages(container, messages, debugMode, state) {
  if (!messages.length) {
    container.innerHTML = renderEmptyState(state);
    return;
  }

  container.innerHTML = messages
    .map((message, index) => renderMessage(message, index, debugMode))
    .join("");
}

function renderEmptyState(state) {
  const pageInsight = buildPageInsight(state);
  return `
    <section class="panel-empty">
      <h2 class="panel-empty-title">Sensa 已就绪</h2>
      <p class="panel-empty-text">Sensa 不只是普通对话 AI。它可以读取当前网页的标题、正文、结构和可见交互元素，也可以把当前页面截图一起发送给大模型，让回答建立在你正在浏览的网页上下文之上。</p>
      <p class="panel-empty-text panel-empty-greeting">${escapeHtml(pageInsight)}</p>
      <p class="panel-empty-text">你可以直接让我总结当前页面、提取重点、解释表格或按钮区域，或者结合截图分析你现在看到的界面。</p>
    </section>
  `;
}

function buildPageInsight(state) {
  const pageSnapshot = getFreshPageSnapshot(state);
  const page = pageSnapshot?.page || {};
  const pageTitle = page.title || state?.currentPageTitle || "当前网页";
  const host = simplifyHostname(page.hostname || state?.currentPageUrl || "");
  const activity = inferPageActivity(pageSnapshot);

  if (host) {
    return `我看到你当前在浏览「${pageTitle}」(${host})。看起来你正在${activity}，要不要我先帮你快速总结这个页面的重点？`;
  }

  return `我看到你当前在浏览「${pageTitle}」。看起来你正在${activity}，要不要我先帮你快速总结这个页面的重点？`;
}

function inferPageActivity(context) {
  if (!context || typeof context !== "object") {
    return "了解这个网页的内容";
  }

  if (context.selection) {
    return "查看你刚选中的那段内容";
  }

  const activeElement = context.activeElement || null;
  const activeLabel = normalizePromptText(
    activeElement?.placeholder || activeElement?.text || ""
  );
  if (activeLabel) {
    return `填写或编辑「${activeLabel}」相关内容`;
  }

  const headings = Array.isArray(context.headings) ? context.headings.filter(Boolean) : [];
  const buttons = Array.isArray(context.buttons) ? context.buttons.filter(Boolean) : [];
  const tables = Array.isArray(context.tables) ? context.tables : [];
  const lists = Array.isArray(context.lists) ? context.lists : [];
  const visibleText = String(context.visibleTextExcerpt || "");

  if (tables.length) {
    return "查看一组表格或数据";
  }

  if (containsKeyword(buttons, ["搜索", "查询", "筛选", "search", "filter"])) {
    return "搜索或筛选页面信息";
  }

  if (containsKeyword(headings, ["登录", "注册", "login", "sign in", "sign up"])) {
    return "处理登录或注册相关内容";
  }

  if (lists.length) {
    return "浏览一组列表信息";
  }

  if (headings.length) {
    return `阅读「${normalizePromptText(headings[0])}」相关内容`;
  }

  if (containsKeyword([visibleText], ["价格", "涨跌", "成交", "market", "price", "stock"])) {
    return "查看行情或价格信息";
  }

  return "了解这个网页的内容";
}

function getFreshPageSnapshot(state) {
  const snapshot = state?.pageSnapshot || null;
  const snapshotUrl = String(snapshot?.page?.url || "").trim();
  const currentUrl = String(state?.currentPageUrl || "").trim();

  if (!snapshotUrl || !currentUrl || snapshotUrl !== currentUrl) {
    return null;
  }

  return snapshot;
}

function containsKeyword(values, keywords) {
  const haystack = values.join(" ").toLowerCase();
  return keywords.some((keyword) => haystack.includes(String(keyword).toLowerCase()));
}

function simplifyHostname(input) {
  const raw = String(input || "").trim();
  if (!raw) {
    return "";
  }

  try {
    const url = raw.startsWith("http://") || raw.startsWith("https://") ? new URL(raw) : null;
    return (url ? url.hostname : raw).replace(/^www\./i, "");
  } catch (error) {
    return raw.replace(/^https?:\/\//i, "").replace(/^www\./i, "").split("/")[0];
  }
}

function normalizePromptText(text) {
  return String(text || "")
    .replace(/\s+/g, " ")
    .trim()
    .slice(0, 36);
}

function renderMessage(message, index, debugMode) {
  const label = message.role === "assistant" ? "AI" : "你";
  const messageMeta = normalizeAssistantMeta(message);
  if (message.role === "assistant" && message.streaming && !String(message.text || "").trim()) {
    return `
      <article class="message assistant is-streaming">
        <div class="message-streaming">
          <span class="message-meta-text">AI</span>
          <span class="message-streaming-text">正在生成...</span>
        </div>
      </article>
    `;
  }
  const details =
    debugMode && message.details
      ? `
      <details class="message-details">
        <summary>本轮详细信息</summary>
        <div class="message-details-body">
          ${
            message.details.screenshotDataUrl
              ? `<img class="message-screenshot" src="${message.details.screenshotDataUrl}" alt="Captured screenshot" />`
              : message.details.note
              ? `<div class="message-detail-note">${escapeHtml(message.details.note)}</div>`
              : ""
          }
          <pre class="message-context">${escapeHtml(message.details.contextPreview || "")}</pre>
        </div>
      </details>
    `
      : "";

  return `
    <article class="message ${message.role}">
      <div class="message-meta">
        <span class="message-meta-text">${escapeHtml(label)}</span>
      </div>
      <div class="message-bubble">
        <div class="message-text">${markdownToHtml(message.text || "", message.role === "user")}</div>
        ${details}
      </div>
      <div class="message-actions">
        <span class="message-runtime-meta"${messageMeta ? "" : " hidden"}>${escapeHtml(messageMeta)}</span>
        <button class="message-copy-button" type="button" data-copy-index="${index}">复制</button>
      </div>
    </article>
  `;
}

function normalizeAssistantMeta(message) {
  if (message.role !== "assistant") {
    return "";
  }

  const meta = String(message.meta || "").trim();
  if (!meta || meta === "AI") {
    return "";
  }

  return meta;
}

function markdownToHtml(markdown, isPlainText) {
  if (isPlainText) {
    return `<p>${renderInline(escapeHtml(markdown))}</p>`;
  }

  const source = String(markdown || "").trim();
  if (!source) {
    return "";
  }

  const lines = source.replace(/\r\n/g, "\n").split("\n");
  const blocks = [];
  let paragraph = [];
  let listItems = [];

  const flushParagraph = () => {
    if (!paragraph.length) {
      return;
    }
    blocks.push(`<p>${renderInline(escapeHtml(paragraph.join(" ")))}</p>`);
    paragraph = [];
  };

  const flushList = () => {
    if (!listItems.length) {
      return;
    }
    blocks.push(`<ul>${listItems.map((item) => `<li>${renderInline(escapeHtml(item))}</li>`).join("")}</ul>`);
    listItems = [];
  };

  for (const rawLine of lines) {
    const line = rawLine.trim();
    if (!line) {
      flushParagraph();
      flushList();
      continue;
    }

    const headingMatch = line.match(/^(#{1,3})\s+(.*)$/);
    if (headingMatch) {
      flushParagraph();
      flushList();
      const level = Math.min(headingMatch[1].length, 3);
      blocks.push(`<h${level}>${renderInline(escapeHtml(headingMatch[2]))}</h${level}>`);
      continue;
    }

    const bulletMatch = line.match(/^[-*]\s+(.*)$/);
    if (bulletMatch) {
      flushParagraph();
      listItems.push(bulletMatch[1]);
      continue;
    }

    const orderedMatch = line.match(/^\d+\.\s+(.*)$/);
    if (orderedMatch) {
      flushParagraph();
      listItems.push(orderedMatch[1]);
      continue;
    }

    flushList();
    paragraph.push(line);
  }

  flushParagraph();
  flushList();
  return blocks.join("");
}

function renderInline(text) {
  let html = text;
  html = html.replace(/`([^`]+)`/g, "<code>$1</code>");
  html = html.replace(/\*\*([^*]+)\*\*/g, "<strong>$1</strong>");
  html = html.replace(/\*([^*]+)\*/g, "<em>$1</em>");
  return html;
}
