import { describe, it } from "node:test";
import assert from "node:assert/strict";

import {
  calculateNextCheckTime,
  STATUS,
  MAX_RETRIES,
  syncScrapedMessages,
} from "../src/chat-scheduler.js";

function createChatMessagesSupabase(existingMessages = []) {
  const insertedRows = [];

  return {
    insertedRows,
    from(table) {
      assert.equal(table, "chat_messages");

      return {
        select() {
          return this;
        },
        eq() {
          return this;
        },
        order() {
          return Promise.resolve({ data: existingMessages, error: null });
        },
        insert(rows) {
          insertedRows.push(...rows);
          return Promise.resolve({ error: null });
        },
      };
    },
  };
}

describe("chat-scheduler", () => {
  describe("calculateNextCheckTime", () => {
    it("retryCount=0 → 约 3 分钟后", () => {
      const before = Date.now();
      const result = new Date(calculateNextCheckTime(0)).getTime();
      const diff = result - before;
      // 应在 2.5 到 3.5 分钟之间
      assert.ok(diff >= 2.5 * 60_000 && diff <= 3.5 * 60_000, `差值 ${diff}ms 应约 3 分钟`);
    });

    it("retryCount=1 → 约 6 分钟后", () => {
      const before = Date.now();
      const result = new Date(calculateNextCheckTime(1)).getTime();
      const diff = result - before;
      assert.ok(diff >= 5.5 * 60_000 && diff <= 6.5 * 60_000, `差值 ${diff}ms 应约 6 分钟`);
    });

    it("retryCount=2 → 约 12 分钟后", () => {
      const before = Date.now();
      const result = new Date(calculateNextCheckTime(2)).getTime();
      const diff = result - before;
      assert.ok(diff >= 11.5 * 60_000 && diff <= 12.5 * 60_000, `差值 ${diff}ms 应约 12 分钟`);
    });

    it("高 retryCount 不超过 60 分钟上限", () => {
      const before = Date.now();
      const result = new Date(calculateNextCheckTime(10)).getTime();
      const diff = result - before;
      // 3 * 2^10 = 3072 分钟，应该被 cap 到 60
      assert.ok(diff <= 61 * 60_000, `差值 ${diff}ms 不应超过 61 分钟`);
      assert.ok(diff >= 59 * 60_000, `差值 ${diff}ms 应至少 59 分钟`);
    });

    it("返回有效的 ISO 时间字符串", () => {
      const result = calculateNextCheckTime(0);
      assert.ok(!Number.isNaN(Date.parse(result)), `应返回有效日期: ${result}`);
    });
  });

  describe("STATUS 常量", () => {
    it("包含所有必要状态", () => {
      const expected = [
        "PENDING_SEND", "WAITING_REPLY",
        "R1_PASSED", "R2_PASSED", "R3_PASSED", "R4_PASSED",
        "REJECTED", "TIMEOUT_REJECTED", "COMPLETED", "HUMAN_TAKEOVER",
      ];
      for (const s of expected) {
        assert.ok(STATUS[s], `缺少状态: ${s}`);
        assert.equal(STATUS[s], s);
      }
    });
  });

  describe("MAX_RETRIES", () => {
    it("应为正整数", () => {
      assert.ok(MAX_RETRIES > 0);
      assert.equal(MAX_RETRIES, Math.floor(MAX_RETRIES));
    });
  });

  describe("syncScrapedMessages", () => {
    it("只补写真实新增的旺旺消息，并忽略已有 LLM 日志", async () => {
      const supabase = createChatMessagesSupabase([
        {
          direction: "SENT",
          content: "您好，请问有货吗？",
          llm_intent: null,
          created_at: "2025-01-01T00:00:00.000Z",
        },
        {
          direction: "RECEIVED",
          content: "有货的",
          llm_intent: null,
          created_at: "2025-01-01T00:01:00.000Z",
        },
        {
          direction: "RECEIVED",
          content: "[LLM 分析] passed=true",
          llm_intent: { passed: true },
          created_at: "2025-01-01T00:01:30.000Z",
        },
      ]);

      const result = await syncScrapedMessages(supabase, {
        chatId: "chat-001",
        round: 1,
        messages: [
          { sender: "self", text: "您好，请问有货吗？" },
          { sender: "other", text: "有货的" },
          { sender: "other", text: "价格 10 元，明天可发" },
        ],
      });

      assert.equal(result.appendedCount, 1);
      assert.deepEqual(supabase.insertedRows, [
        {
          chat_id: "chat-001",
          round: 1,
          direction: "RECEIVED",
          content: "价格 10 元，明天可发",
        },
      ]);
    });

    it("抓取窗口与已落库消息完全重合时不重复写入", async () => {
      const supabase = createChatMessagesSupabase([
        {
          direction: "SENT",
          content: "您好，请问有货吗？",
          llm_intent: null,
          created_at: "2025-01-01T00:00:00.000Z",
        },
        {
          direction: "RECEIVED",
          content: "有货的",
          llm_intent: null,
          created_at: "2025-01-01T00:01:00.000Z",
        },
      ]);

      const result = await syncScrapedMessages(supabase, {
        chatId: "chat-001",
        round: 1,
        messages: [
          { sender: "self", text: "您好，请问有货吗？" },
          { sender: "other", text: "有货的" },
        ],
      });

      assert.equal(result.appendedCount, 0);
      assert.deepEqual(supabase.insertedRows, []);
    });
  });
});
