import assert from 'node:assert/strict'
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
import test from 'node:test'
import { fileURLToPath } from 'node:url'

const __dirname = path.dirname(fileURLToPath(import.meta.url))
const workerRoot = path.resolve(__dirname, '../..')

function execMigrationOnce(db, file) {
  try {
    db.exec(fs.readFileSync(path.join(workerRoot, file), 'utf8'))
  } catch (error) {
    if (!/duplicate column|already exists/i.test(error?.message || '')) throw error
  }
}

function cloudTurn(text, turn) {
  const events = [
    ...(turn === 1 ? [
      `id: evt_${turn}_write`,
      'event: agent.tool_use',
      `data: ${JSON.stringify({ type: 'agent.tool_use', turn_id: `turn_${turn}`, name: 'Write', input: { file_path: '/data/SKILL.md', content: '# 云端流程审核' } })}`,
      '',
    ] : []),
    `id: evt_${turn}_1`,
    'event: agent.message',
    `data: ${JSON.stringify({ type: 'agent.message', turn_id: `turn_${turn}`, content: [{ type: 'text', text }] })}`,
    '',
    `id: evt_${turn}_2`,
    'event: session.status_idle',
    `data: ${JSON.stringify({ type: 'session.status_idle', turn_id: `turn_${turn}` })}`,
    '',
    '',
  ]
  return new Response(events.join('\n'), { status: 200, headers: { 'Content-Type': 'text/event-stream' } })
}

test('AIPROS multi-turn requests reuse the same QODER Cloud session', async (t) => {
  const tempRoot = fs.mkdtempSync(path.join(os.tmpdir(), 'aipros-qoder-session-'))
  process.env.DB_PATH = path.join(tempRoot, 'test.db')
  process.env.OUTPUTS_DIR = path.join(tempRoot, 'outputs')

  const originalFetch = globalThis.fetch
  let createCalls = 0
  let streamCalls = 0
  let messageCalls = 0
  globalThis.fetch = async (url, options = {}) => {
    const value = String(url)
    if (value.endsWith('/sessions') && options.method === 'POST') {
      createCalls += 1
      return Response.json({ id: 'qoder_reused' })
    }
    if (value.includes('/sessions/qoder_reused/events/stream')) {
      streamCalls += 1
      return cloudTurn(streamCalls === 1 ? '第一轮' : '第二轮', streamCalls)
    }
    if (value.endsWith('/sessions/qoder_reused/events') && options.method === 'POST') {
      messageCalls += 1
      return Response.json({ ok: true })
    }
    throw new Error(`unexpected fetch: ${value}`)
  }

  t.after(() => {
    globalThis.fetch = originalFetch
    fs.rmSync(tempRoot, { recursive: true, force: true })
  })

  const { default: app } = await import('../index.js')
  const { rawDB } = await import('../db.js')
  execMigrationOnce(rawDB, 'migrations/0010_runtime_engines.sql')
  execMigrationOnce(rawDB, 'migrations/0011_runtime_engine_api_key.sql')
  execMigrationOnce(rawDB, 'migrations/0014_local_runtime_agents.sql')
  execMigrationOnce(rawDB, 'migrations/0018_qoder_cloud_agent_runtime.sql')
  rawDB.prepare('UPDATE runtime_engines SET enabled = 0, is_active = 0').run()
  rawDB.prepare(`
    UPDATE runtime_engines
    SET enabled = 1, is_active = 1, api_key = 'pat', runtime_id = 'env_1', endpoint_id = 'agent_1',
        endpoint_public_url = 'https://api.qoder.test/api/v1/cloud', purpose_scopes_json = '["create"]'
    WHERE code = 'qoder-cloud-agent'
  `).run()
  rawDB.prepare(`
    UPDATE runtime_agents
    SET runtime_code = 'qoder-cloud-agent', applies_to_json = '["create"]', enabled = 1
    WHERE id = 'agent-skill-creator'
  `).run()

  const headers = { 'Content-Type': 'application/json', 'X-User-Email': '494161546@qq.com' }
  const first = await app.request('/api/skill-run/stream', {
    method: 'POST', headers,
    body: JSON.stringify({ mode: 'create', messages: [{ role: 'user', content: '第一轮' }] }),
  })
  const firstText = await first.text()
  const sessionId = firstText.match(/"sessionId":"([^"]+)"/)?.[1]
  assert.ok(sessionId)
  assert.match(firstText, /第一轮/)
  assert.match(firstText, /"t":"artifact"[\s\S]*SKILL\.md/)
  const mirrored = await app.request(
    `/api/skill-run/outputs/${encodeURIComponent(sessionId)}/SKILL.md`,
    { headers: { 'X-User-Email': '494161546@qq.com' } },
  )
  assert.equal(mirrored.status, 200)
  assert.match(await mirrored.text(), /云端流程审核/)

  const second = await app.request('/api/skill-run/stream', {
    method: 'POST', headers,
    body: JSON.stringify({
      mode: 'create',
      sessionId,
      messages: [
        { role: 'user', content: '第一轮' },
        { role: 'assistant', content: '请补充' },
        { role: 'user', content: '第二轮' },
      ],
    }),
  })
  const secondText = await second.text()
  assert.match(secondText, /第二轮/)
  assert.equal(createCalls, 1)
  assert.equal(messageCalls, 2)
})
