import http from 'node:http'

const DEFAULT_DEEPSEEK_MODEL = 'deepseek-chat'
const DEFAULT_DEEPSEEK_API_KEY = 'sgclaw-smoke-test-key'

const BAIDU_URL = 'https://www.baidu.com'
const BAIDU_DOMAIN = 'www.baidu.com'
const BAIDU_INPUT_SELECTOR = '#kw'
const BAIDU_BUTTON_SELECTOR = '#su'
const ZHIHU_URL = 'https://www.zhihu.com/search'
const ZHIHU_DOMAIN = 'www.zhihu.com'

export function buildSmokeEnv(baseUrl, baseEnv = process.env) {
  return {
    ...baseEnv,
    DEEPSEEK_API_KEY: DEFAULT_DEEPSEEK_API_KEY,
    DEEPSEEK_BASE_URL: baseUrl,
    DEEPSEEK_MODEL: DEFAULT_DEEPSEEK_MODEL,
  }
}

export function buildChatCompletionResponse(requestBody) {
  const instruction = latestUserInstruction(requestBody?.messages ?? [])
  const plan = instructionPlan(instruction)
  const isFinalRound = (requestBody?.messages ?? []).some((message) => message?.role === 'tool')

  if (isFinalRound) {
    return {
      id: `chatcmpl-smoke-final-${plan.key}`,
      object: 'chat.completion',
      created: unixTimeSeconds(),
      model: DEFAULT_DEEPSEEK_MODEL,
      choices: [{
        index: 0,
        message: {
          role: 'assistant',
          content: plan.summary,
        },
        finish_reason: 'stop',
      }],
      usage: {
        prompt_tokens: 32,
        completion_tokens: 8,
        total_tokens: 40,
      },
    }
  }

  return {
    id: `chatcmpl-smoke-tools-${plan.key}`,
    object: 'chat.completion',
    created: unixTimeSeconds(),
    model: DEFAULT_DEEPSEEK_MODEL,
    choices: [{
      index: 0,
      message: {
        role: 'assistant',
        content: '',
        tool_calls: plan.toolCalls,
      },
      finish_reason: 'tool_calls',
    }],
    usage: {
      prompt_tokens: 24,
      completion_tokens: 12,
      total_tokens: 36,
    },
  }
}

export async function startFakeDeepSeekServer() {
  const requests = []
  const server = http.createServer(async (req, res) => {
    try {
      if (req.method !== 'POST') {
        res.writeHead(405, {'content-type': 'application/json'})
        res.end(JSON.stringify({error: 'method not allowed'}))
        return
      }

      const body = await readJsonBody(req)
      requests.push({
        method: req.method,
        url: req.url || '/',
        body,
      })

      const response = buildChatCompletionResponse(body)
      res.writeHead(200, {'content-type': 'application/json'})
      res.end(JSON.stringify(response))
    } catch (error) {
      res.writeHead(500, {'content-type': 'application/json'})
      res.end(JSON.stringify({
        error: error instanceof Error ? error.message : String(error),
      }))
    }
  })

  await new Promise((resolve, reject) => {
    server.once('error', reject)
    server.listen(0, '127.0.0.1', resolve)
  })

  const address = server.address()
  if (!address || typeof address === 'string') {
    server.close()
    throw new Error('failed to bind fake DeepSeek server')
  }

  return {
    baseUrl: `http://127.0.0.1:${address.port}`,
    requests,
    close: () => new Promise((resolve, reject) => {
      server.close((error) => error ? reject(error) : resolve())
    }),
  }
}

function latestUserInstruction(messages) {
  for (let index = messages.length - 1; index >= 0; index -= 1) {
    const message = messages[index]
    if (message?.role === 'user' && typeof message.content === 'string' && message.content.trim()) {
      return normalizeSmokeInstruction(message.content)
    }
  }

  throw new Error('missing user instruction in DeepSeek smoke request')
}

export function normalizeSmokeInstruction(rawInstruction) {
  return rawInstruction.trim().replace(/^(?:\[[^\]]+\]\s*)+/, '')
}

function instructionPlan(instruction) {
  const baiduQuery = extractQuery(instruction, ['打开百度搜索', '打开百度并搜索'])
  if (baiduQuery) {
    const url = new URL('https://www.baidu.com/s')
    url.searchParams.set('wd', baiduQuery)

    return {
      key: 'baidu',
      summary: `已在百度搜索${baiduQuery}`,
      toolCalls: [
        browserToolCall('call_baidu_1', {
          action: 'navigate',
          expected_domain: BAIDU_DOMAIN,
          url: url.toString(),
        }),
      ],
    }
  }

  const zhihuQuery = extractQuery(instruction, ['打开知乎搜索', '打开知乎并搜索'])
  if (zhihuQuery) {
    const url = new URL(ZHIHU_URL)
    url.searchParams.set('type', 'content')
    url.searchParams.set('q', zhihuQuery)

    return {
      key: 'zhihu',
      summary: `已在知乎搜索${zhihuQuery}`,
      toolCalls: [
        browserToolCall('call_zhihu_1', {
          action: 'navigate',
          expected_domain: ZHIHU_DOMAIN,
          url: url.toString(),
        }),
      ],
    }
  }

  throw new Error(`unsupported smoke instruction: ${instruction}`)
}

function extractQuery(instruction, prefixes) {
  for (const prefix of prefixes) {
    if (instruction.startsWith(prefix)) {
      const query = instruction.slice(prefix.length).trim()
      if (!query) {
        throw new Error(`missing search query in instruction: ${instruction}`)
      }
      return query
    }
  }

  return null
}

function browserToolCall(id, args) {
  return {
    id,
    type: 'function',
    function: {
      name: 'browser_action',
      arguments: JSON.stringify(args),
    },
  }
}

function readJsonBody(req) {
  return new Promise((resolve, reject) => {
    let raw = ''
    req.setEncoding('utf8')
    req.on('data', (chunk) => {
      raw += chunk
    })
    req.on('end', () => {
      try {
        resolve(JSON.parse(raw || '{}'))
      } catch (error) {
        reject(error)
      }
    })
    req.on('error', reject)
  })
}

function unixTimeSeconds() {
  return Math.floor(Date.now() / 1000)
}
