import { Hono } from 'hono'
import {
  getRuntimeRow,
  listAgents,
  listRuntimeRows,
  rowToRuntime,
  saveAgent,
  setActiveRuntime,
  testLocalRuntime,
  updateRuntime,
} from '../runtime/runtime-registry.js'
import {
  buildAgentRunChatCompletionsRequest,
  extractOpenAIChunkText,
  isAgentRunIntegrationUrl,
} from '../runtime/agentrun-openai.js'
import { missingAgentRunConfig } from '../runtime/agentrun-config.js'
import {
  buildQoderCloudPrompt,
  runQoderCloudAgent,
  missingQoderCloudAgentConfig,
  QODER_CLOUD_AGENT_PROTOCOL,
} from '../runtime/qoder-cloud-agent.js'

const app = new Hono()

const ADMIN_EMAIL = '494161546@qq.com'
const ADMIN_PHONE = '13136092523'

function isAdmin(c) {
  const id = c.get('identity') || {}
  return id.email === ADMIN_EMAIL || id.phone === ADMIN_PHONE
}

async function fetchWithTimeout(url, options = {}, timeoutMs = 30000) {
  const ctrl = new AbortController()
  const timer = setTimeout(() => ctrl.abort(new Error(`timeout after ${timeoutMs}ms`)), timeoutMs)
  try {
    return await fetch(url, { ...options, signal: ctrl.signal })
  } finally {
    clearTimeout(timer)
  }
}

async function testAgentRunRuntime(row) {
  const missing = missingAgentRunConfig(row)
  if (missing.length) return { ok: false, message: `请先补齐 AgentRun 配置：${missing.join(', ')}` }
  const t0 = Date.now()
  try {
    if (isAgentRunIntegrationUrl(row.endpoint_public_url)) {
      const { url, options } = buildAgentRunChatCompletionsRequest({
        endpointPublicUrl: row.endpoint_public_url,
        invocationKey: row.api_key,
        sessionId: globalThis.crypto?.randomUUID?.() || `test-${Date.now()}`,
        messages: [{ role: 'user', content: 'Hi' }],
        stream: false,
      })
      const resp = await fetchWithTimeout(url, options, 30000)
      const data = await resp.json().catch(async () => ({ raw: await resp.text().catch(() => '') }))
      if (!resp.ok) return { ok: false, message: data?.error?.message || data?.message || data?.raw || `HTTP ${resp.status}` }
      return {
        ok: true,
        model: row.endpoint_name || 'Default',
        latencyMs: Date.now() - t0,
        content: extractOpenAIChunkText(data).slice(0, 80) || 'AgentRun Runtime 已响应',
      }
    }

    const { AgentRuntimeClient, Config } = await import('@agentrun/sdk')
    const client = new AgentRuntimeClient(new Config({
      accessKeyId: row.access_key_id,
      accessKeySecret: row.access_key_secret,
      securityToken: row.security_token || undefined,
      accountId: row.account_id,
      regionId: row.region_id || 'cn-hangzhou',
      readTimeout: 30000,
      timeout: 30000,
    }))
    const resp = await client.invokeOpenai({
      agentRuntimeName: row.runtime_name,
      agentRuntimeEndpointName: row.endpoint_name || 'default',
      messages: [{ role: 'user', content: 'Hi' }],
      stream: false,
    })
    return {
      ok: true,
      model: row.endpoint_name || 'default',
      latencyMs: Date.now() - t0,
      content: String(resp?.choices?.[0]?.message?.content || '').slice(0, 80) || 'AgentRun Runtime 已响应',
    }
  } catch (e) {
    return { ok: false, message: e?.message || String(e) }
  }
}

async function testQoderCloudAgentRuntime(row) {
  const missing = missingQoderCloudAgentConfig(row)
  if (missing.length) return { ok: false, message: `请先补齐 QODER Cloud Agent 配置：${missing.join(', ')}` }
  const t0 = Date.now()
  const ctrl = new AbortController()
  const timer = setTimeout(() => ctrl.abort(new Error('timeout after 30000ms')), 30000)
  try {
    let content = ''
    const prompt = buildQoderCloudPrompt({
      mode: 'test',
      chatMessages: [{ role: 'user', content: '请只回复：AIPROS Runtime OK' }],
    })
    for await (const evt of runQoderCloudAgent({ runtimeRow: row, prompt, signal: ctrl.signal })) {
      if (evt?.t === 'delta') content += evt.v || ''
      if (evt?.t === 'error') return { ok: false, message: evt.v || 'QODER Cloud Agent 执行失败' }
      if (content.length > 120) break
    }
    return {
      ok: true,
      model: 'QODER Cloud Agent',
      latencyMs: Date.now() - t0,
      content: content.slice(0, 80) || 'QODER Cloud Agent 已响应',
    }
  } catch (e) {
    return { ok: false, message: e?.message || String(e) }
  } finally {
    clearTimeout(timer)
  }
}

app.get('/', async (c) => {
  const rows = await listRuntimeRows()
  const agents = await listAgents()
  return c.json({ runtimes: rows.map(rowToRuntime), agents })
})

app.patch('/:code', async (c) => {
  if (!isAdmin(c)) return c.json({ error: '无权限' }, 403)
  const code = c.req.param('code')
  const body = await c.req.json().catch(() => ({}))
  const result = await updateRuntime(code, body)
  if (result.error) return c.json({ error: result.error }, result.status || 400)
  return c.json(result)
})

app.post('/:code/active', async (c) => {
  if (!isAdmin(c)) return c.json({ error: '无权限' }, 403)
  const result = await setActiveRuntime(c.req.param('code'))
  if (result.error) return c.json({ error: result.error }, result.status || 400)
  return c.json(result)
})

app.post('/:code/test', async (c) => {
  if (!isAdmin(c)) return c.json({ error: '无权限' }, 403)
  const row = await getRuntimeRow(c.req.param('code'))
  if (!row) return c.json({ ok: false, message: '运行时不存在' }, 404)
  if (row.protocol === 'local-cli') return c.json(await testLocalRuntime(row))
  if (row.protocol === 'agentrun') return c.json(await testAgentRunRuntime(row))
  if (row.protocol === QODER_CLOUD_AGENT_PROTOCOL) return c.json(await testQoderCloudAgentRuntime(row))
  return c.json({ ok: false, message: `暂不支持测试协议：${row.protocol}` })
})

app.put('/agents/:id', async (c) => {
  if (!isAdmin(c)) return c.json({ error: '无权限' }, 403)
  const body = await c.req.json().catch(() => ({}))
  const agent = await saveAgent(c.req.param('id'), body)
  return c.json({ ok: true, agent })
})

export default app
