import { CloseBotClient, err } from "../client.js";
import type { ToolDefinition, ToolResult, BotMetricMessage, ListLeadDto } from "../types.js";

export const tools: ToolDefinition[] = [
  {
    name: "test_console_app",
    description: "Interactive test session viewer showing conversation messages, current step, and session list. Returns HTML visualization.",
    inputSchema: {
      type: "object",
      properties: {
        botId: { type: "string", description: "The bot ID" },
        leadId: { type: "string", description: "Optional: specific test session lead ID to view conversation" },
      },
      required: ["botId"],
    },
  },
];

function escapeHtml(s: string): string {
  return s.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}

function renderSessionList(sessions: ListLeadDto, botId: string): string {
  const leads = sessions.leads || [];
  const rows = leads
    .map((lead) => {
      const lastMsg = lead.lastMessage ? escapeHtml(lead.lastMessage.slice(0, 60)) : "—";
      const time = lead.lastMessageTime
        ? new Date(lead.lastMessageTime).toLocaleString()
        : "—";
      const direction = lead.lastMessageDirection === "outbound" ? "🤖→" : "←👤";

      return `
        <div style="background:#1a1a2e;border-radius:8px;padding:12px;display:flex;flex-direction:column;gap:4px;">
          <div style="display:flex;justify-content:space-between;">
            <span style="font-weight:600;color:#e0e0e0;font-size:13px;">${escapeHtml(lead.name || "Test Lead")}</span>
            <span style="font-size:11px;color:#666;">${time}</span>
          </div>
          <div style="font-size:12px;color:#888;">${direction} ${lastMsg}${(lead.lastMessage?.length ?? 0) > 60 ? "…" : ""}</div>
          <div style="font-size:10px;color:#555;font-family:monospace;">Lead: ${escapeHtml(lead.id || "")}</div>
        </div>`;
    })
    .join("");

  return `
    <div style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#0d0d1a;color:#e0e0e0;padding:20px;border-radius:16px;">
      <h2 style="margin:0 0 4px;color:#fff;">🧪 Test Console</h2>
      <div style="font-size:12px;color:#666;margin-bottom:16px;">Bot: <code>${escapeHtml(botId)}</code> · ${sessions.total ?? leads.length} session(s)</div>
      <div style="display:flex;flex-direction:column;gap:8px;">
        ${rows || '<div style="color:#666;padding:20px;text-align:center;">No test sessions found. Create one with create_test_session.</div>'}
      </div>
    </div>`;
}

function renderConversation(messages: BotMetricMessage[], botId: string, leadId: string): string {
  const sorted = [...messages].sort(
    (a, b) => new Date(a.timestamp || 0).getTime() - new Date(b.timestamp || 0).getTime()
  );

  const msgHtml = sorted
    .map((msg) => {
      const isBot = msg.fromBot || msg.direction === "outbound";
      const align = isBot ? "flex-end" : "flex-start";
      const bg = isBot ? "#1a3a5c" : "#2a1a3e";
      const border = isBot ? "#2a5a8c" : "#4a2a6e";
      const label = isBot ? "🤖 Bot" : "👤 User";
      const time = msg.timestamp ? new Date(msg.timestamp).toLocaleTimeString() : "";
      const content = msg.message || "[no content]";
      const activities =
        msg.activities && msg.activities.length > 0
          ? `<div style="font-size:10px;color:#666;margin-top:4px;">Activities: ${msg.activities.map((a) => escapeHtml(a.activity || "")).join(", ")}</div>`
          : "";
      const attachments =
        msg.attachments && msg.attachments.length > 0
          ? `<div style="font-size:10px;color:#4ecdc4;margin-top:4px;">📎 ${msg.attachments.length} attachment(s)</div>`
          : "";

      return `
        <div style="display:flex;justify-content:${align};margin:4px 0;">
          <div style="max-width:75%;background:${bg};border:1px solid ${border};border-radius:12px;padding:10px 14px;">
            <div style="display:flex;justify-content:space-between;gap:16px;margin-bottom:4px;">
              <span style="font-size:11px;font-weight:600;color:#aaa;">${label}</span>
              <span style="font-size:10px;color:#555;">${escapeHtml(time)}</span>
            </div>
            <div style="font-size:13px;color:#e0e0e0;white-space:pre-wrap;">${escapeHtml(content)}</div>
            ${activities}${attachments}
            <div style="font-size:9px;color:#444;margin-top:4px;font-family:monospace;">msg: ${escapeHtml(msg.messageId || "")}</div>
          </div>
        </div>`;
    })
    .join("");

  return `
    <div style="font-family:-apple-system,BlinkMacSystemFont,sans-serif;background:#0d0d1a;color:#e0e0e0;padding:20px;border-radius:16px;">
      <h2 style="margin:0 0 4px;color:#fff;">🧪 Test Conversation</h2>
      <div style="font-size:12px;color:#666;margin-bottom:16px;">
        Bot: <code>${escapeHtml(botId)}</code> · Lead: <code>${escapeHtml(leadId)}</code> · ${sorted.length} messages
      </div>
      <div style="background:#111;border-radius:12px;padding:16px;max-height:600px;overflow-y:auto;">
        ${msgHtml || '<div style="color:#666;text-align:center;padding:40px;">No messages yet. Send one with send_test_message.</div>'}
      </div>
      <div style="margin-top:12px;display:flex;gap:8px;font-size:11px;color:#888;">
        <span>💡 Use <code>send_test_message</code> to send messages</span>
        <span>· <code>force_test_step</code> to advance</span>
        <span>· <code>rollback_test_session</code> to undo</span>
      </div>
    </div>`;
}

export async function handler(
  client: CloseBotClient,
  name: string,
  args: Record<string, unknown>
): Promise<ToolResult> {
  try {
    const botId = args.botId as string;
    const leadId = args.leadId as string | undefined;

    if (leadId) {
      const messages = await client.get<BotMetricMessage[]>("/botMetric/messages", {
        leadId,
        maxCount: 100,
      });
      const html = renderConversation(messages, botId, leadId);
      return {
        content: [{ type: "text", text: `Test conversation: ${messages.length} messages` }],
        structuredContent: { type: "html", html },
      };
    }

    const sessions = await client.get<ListLeadDto>(`/bot/${botId}/testSession`, {
      offset: 0,
      maxCount: 50,
    });
    const html = renderSessionList(sessions, botId);
    return {
      content: [
        { type: "text", text: `${sessions.total ?? (sessions.leads?.length || 0)} test sessions for bot ${botId}` },
      ],
      structuredContent: { type: "html", html },
    };
  } catch (error) {
    return err(error);
  }
}
