import { Hono } from 'hono'
import { randomBytes, createHash } from 'node:crypto'
import { DB } from '../db.js'
import { genId } from '../utils/id.js'

const app = new Hono()

function hashKey(raw) {
  return createHash('sha256').update(raw).digest('hex')
}

function generateApiKey() {
  // 生成 sk_live_ 前缀的 API Key
  const bytes = randomBytes(24)
  return 'sk_live_' + bytes.toString('base64url')
}

function isSuperAdmin(identity) {
  return identity?.email === '494161546@qq.com' || identity?.phone === '13136092523'
}

function ownsKey(record, identity) {
  if (!record || !identity) return false
  return (
    (identity.email && record.created_by_email && identity.email === record.created_by_email) ||
    (identity.phone && record.created_by_phone && identity.phone === record.created_by_phone)
  )
}

// POST /api/apikeys - 创建新 API Key
app.post('/', async (c) => {
  const identity = c.get('identity') || {}
  if (!identity.phone && !identity.email) {
    return c.json({ error: 'unauthenticated' }, 401)
  }

  const { skill_id, name } = await c.req.json().catch(() => ({}))
  if (!skill_id) {
    return c.json({ error: 'skill_id is required' }, 400)
  }

  // 验证 skill 存在
  const skill = await DB.prepare('SELECT id, name, status, creator_phone, creator_email FROM skills WHERE id = ?').bind(skill_id).first()
  if (!skill) {
    return c.json({ error: 'skill not found' }, 404)
  }
  if (skill.status !== 'published') {
    return c.json({
      error: 'skill_not_published',
      message: '只有已上线 Skill 才能创建 API Key',
    }, 409)
  }

  // 校验归属权：仅 skill 创建者或超管可创建 key
  const userEmail = identity.email || ''
  const userPhone = identity.phone || ''
  if (!isSuperAdmin(identity)) {
    const isOwner = (skill.creator_phone && skill.creator_phone === userPhone) ||
                    (skill.creator_email && skill.creator_email === userEmail)
    if (!isOwner) {
      return c.json({ error: '无权为此 Skill 创建 API Key' }, 403)
    }
  }

  const rawKey = generateApiKey()
  const id = genId('key')
  const keyHash = hashKey(rawKey)
  const keyPrefix = rawKey.slice(0, 12) + '...'

  await DB.prepare(`
    INSERT INTO api_keys (id, skill_id, name, key_hash, key_prefix, created_by_email, created_by_phone)
    VALUES (?, ?, ?, ?, ?, ?, ?)
  `).bind(id, skill_id, name || 'default', keyHash, keyPrefix, identity.email || '', identity.phone || '').run()

  // 审计
  c.set('audit', {
    action: 'create_api_key',
    targetType: 'api_key',
    targetId: id,
    targetName: name || 'default',
    meta: JSON.stringify({ skill_id, skill_name: skill.name })
  })

  return c.json({
    id,
    skill_id,
    skill_name: skill.name,
    name: name || 'default',
    key: rawKey,  // 仅此一次返回完整 Key
    key_prefix: keyPrefix,
    daily_limit: 1000,
    message: '请妥善保存此 API Key，它不会再次显示'
  }, 201)
})

// GET /api/apikeys - 列出当前用户的所有 Key
app.get('/', async (c) => {
  const identity = c.get('identity') || {}
  if (!identity.phone && !identity.email) {
    return c.json({ error: 'unauthenticated' }, 401)
  }

  const filters = []
  const args = []
  if (identity.email) { filters.push('k.created_by_email = ?'); args.push(identity.email) }
  if (identity.phone) { filters.push('k.created_by_phone = ?'); args.push(identity.phone) }
  if (!filters.length) return c.json({ error: 'unauthenticated' }, 401)

  const sql = `
    SELECT k.id, k.skill_id, k.name, k.key_prefix, k.status, k.daily_limit, k.created_at,
           s.name as skill_name,
           (SELECT COUNT(*) FROM skill_invocations WHERE api_key_id = k.id) as total_calls
    FROM api_keys k
    LEFT JOIN skills s ON s.id = k.skill_id
    WHERE ${filters.join(' OR ')}
    ORDER BY k.created_at DESC
  `
  const { results } = await DB.prepare(sql).bind(...args).all()

  return c.json({ data: results || [] })
})

// DELETE /api/apikeys/:keyId - 吊销 Key
app.delete('/:keyId', async (c) => {
  const identity = c.get('identity') || {}
  if (!identity.phone && !identity.email) {
    return c.json({ error: 'unauthenticated' }, 401)
  }

  const keyId = c.req.param('keyId')
  const record = await DB.prepare('SELECT * FROM api_keys WHERE id = ?').bind(keyId).first()
  if (!record) {
    return c.json({ error: 'not found' }, 404)
  }

  // 验证归属
  if (!ownsKey(record, identity) && !isSuperAdmin(identity)) {
    return c.json({ error: 'forbidden' }, 403)
  }

  await DB.prepare('UPDATE api_keys SET status = ? WHERE id = ?').bind('revoked', keyId).run()

  c.set('audit', {
    action: 'revoke_api_key',
    targetType: 'api_key',
    targetId: keyId,
    targetName: record.name
  })

  return c.json({ message: 'API Key 已吊销' })
})

// GET /api/apikeys/:keyId/stats - 调用统计
app.get('/:keyId/stats', async (c) => {
  const identity = c.get('identity') || {}
  if (!identity.phone && !identity.email) {
    return c.json({ error: 'unauthenticated' }, 401)
  }

  const keyId = c.req.param('keyId')
  const record = await DB.prepare('SELECT * FROM api_keys WHERE id = ?').bind(keyId).first()
  if (!record) return c.json({ error: 'not found' }, 404)
  if (!ownsKey(record, identity) && !isSuperAdmin(identity)) {
    return c.json({ error: 'forbidden' }, 403)
  }

  // 总调用数
  const total = await DB.prepare(
    'SELECT COUNT(*) as n FROM skill_invocations WHERE api_key_id = ?'
  ).bind(keyId).first()

  // 今日调用数
  const todayStart = Math.floor(new Date().setHours(0, 0, 0, 0) / 1000)
  const today = await DB.prepare(
    'SELECT COUNT(*) as n FROM skill_invocations WHERE api_key_id = ? AND ts >= ?'
  ).bind(keyId, todayStart).first()

  // 错误数
  const errors = await DB.prepare(
    'SELECT COUNT(*) as n FROM skill_invocations WHERE api_key_id = ? AND response_status != ?'
  ).bind(keyId, 'success').first()

  // 最近10条调用记录
  const { results: recent } = await DB.prepare(
    'SELECT ts, skill_name, response_status, latency_ms FROM skill_invocations WHERE api_key_id = ? ORDER BY ts DESC LIMIT 10'
  ).bind(keyId).all()

  // 平均延迟
  const avgLatency = await DB.prepare(
    'SELECT AVG(latency_ms) as avg_ms FROM skill_invocations WHERE api_key_id = ?'
  ).bind(keyId).first()

  return c.json({
    total_calls: total?.n || 0,
    today_calls: today?.n || 0,
    error_count: errors?.n || 0,
    success_rate: total?.n > 0 ? ((total.n - (errors?.n || 0)) / total.n * 100).toFixed(1) + '%' : '100%',
    avg_latency_ms: Math.round(avgLatency?.avg_ms || 0),
    recent_calls: recent || []
  })
})

export default app
