import test from "node:test"
import assert from "node:assert/strict"
import { mkdir, mkdtemp, rm, writeFile } from "node:fs/promises"
import { tmpdir } from "node:os"
import path from "node:path"

import { TaskPanelService } from "../src/main/services/task-panel-service.ts"

async function withService<T>(run: (service: TaskPanelService, userDataPath: string) => Promise<T>) {
  const userDataPath = await mkdtemp(path.join(tmpdir(), "qjc-task-panel-"))
  try {
    const service = new TaskPanelService(userDataPath)
    return await run(service, userDataPath)
  } finally {
    await rm(userDataPath, { recursive: true, force: true })
  }
}

test("returns an empty list for empty state and invalid dates", async () => {
  await withService(async (service) => {
    assert.deepEqual(await service.listByDate("2026-05-15"), [])
    assert.deepEqual(await service.listByDate("2026/05/15"), [])
  })
})

test("records expert workspace executions and sorts newest first", async () => {
  await withService(async (service) => {
    await service.recordWorkspaceExecution({
      sessionId: "session-xhs",
      runId: "run-xhs",
      date: "2026-05-15",
      expertName: "小红书专家",
      taskTitle: "整理小红书选题",
      completedAt: "2026-05-15T02:00:00.000Z",
      artifacts: [
        { id: "a", name: "xhs.md", kind: "文档", path: "/tmp/xhs.md", url: "/tmp/xhs.md", producedAt: "2026-05-15 10:00:00" }
      ]
    })
    await service.recordWorkspaceExecution({
      sessionId: "session-douyin",
      runId: "run-douyin",
      date: "2026-05-15",
      expertName: "抖音专家",
      taskTitle: "整理抖音脚本",
      completedAt: "2026-05-15T03:00:00.000Z",
      artifacts: [
        { id: "b", name: "douyin.csv", kind: "表格", path: "/tmp/douyin.csv", url: "/tmp/douyin.csv", producedAt: "2026-05-15 11:00:00" }
      ]
    })

    const items = await service.listByDate("2026-05-15")
    assert.equal(items.length, 2)
    assert.equal(items[0]?.expertName, "抖音专家")
    assert.equal(items[1]?.expertName, "小红书专家")
    assert.equal(items[0]?.messageCount, 2)
  })
})

test("dedupes repeated runs and repeated artifact paths", async () => {
  await withService(async (service) => {
    const input = {
      sessionId: "session-xhs",
      runId: "run-xhs",
      date: "2026-05-15",
      expertName: "小红书专家",
      taskTitle: "整理小红书选题",
      completedAt: "2026-05-15T02:00:00.000Z",
      artifacts: [
        { id: "one", name: "xhs.md", kind: "文档", path: "/tmp/xhs.md", url: "/tmp/xhs.md", producedAt: "2026-05-15 10:00:00" },
        { id: "two", name: "xhs-copy.md", kind: "文档", path: "/tmp/xhs.md", url: "/tmp/xhs.md", producedAt: "2026-05-15 10:00:00" }
      ]
    }
    await service.recordWorkspaceExecution(input)
    await service.recordWorkspaceExecution(input)

    const items = await service.listByDate("2026-05-15")
    assert.equal(items.length, 1)
    assert.equal(items[0]?.artifacts.length, 1)
  })
})

test("preserves all tasks when multiple executions are recorded concurrently", async () => {
  await withService(async (service) => {
    await Promise.all(Array.from({ length: 12 }, (_, index) => service.recordWorkspaceExecution({
      sessionId: `session-${index}`,
      runId: `run-${index}`,
      date: "2026-05-15",
      expertName: index % 2 === 0 ? "小红书专家" : "抖音专家",
      taskTitle: `并发任务 ${index}`,
      completedAt: `2026-05-15T02:00:${String(index).padStart(2, "0")}.000Z`,
      artifacts: [
        { id: `artifact-${index}`, name: `result-${index}.md`, kind: "文档", path: `/tmp/result-${index}.md`, url: `/tmp/result-${index}.md` }
      ]
    })))

    const items = await service.listByDate("2026-05-15")
    assert.equal(items.length, 12)
    assert.deepEqual(new Set(items.map((item) => item.id)).size, 12)
  })
})

test("falls back to empty state when the state file is corrupt", async () => {
  await withService(async (service, userDataPath) => {
    await mkdir(path.join(userDataPath, "task-panel"), { recursive: true })
    await writeFile(path.join(userDataPath, "task-panel", "state.json"), "{bad json", "utf8")

    assert.deepEqual(await service.listByDate("2026-05-15"), [])
  })
})
