// 腾讯EdgeOne边缘函数：支持Gravatar(邮箱/MD5)和QQ头像(QQ号)代理，全程UTF-8编码
addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request))
})

/**
 * 处理请求并代理返回对应的头像（Gravatar或QQ头像）
 * @param {Request} request
 */
async function handleRequest(request) {
  try {
    const url = new URL(request.url)
    const pathParts = url.pathname.split('/').filter(part => part)
    
    // 路径格式校验：必须为/avatar/[参数]
    if (pathParts.length !== 2 || pathParts[0] !== 'avatar') {
      return new Response(
        '请使用正确的路径格式：\n' +
        '/avatar/QQ号（如/avatar/123456）\n' +
        '/avatar/邮箱（如/avatar/user@example.com）\n' +
        '/avatar/MD5（如/avatar/md5hashvalue）',
        {
          status: 400,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        }
      )
    }
    
    const param = pathParts[1]
    if (!param) {
      return new Response(
        '请提供参数（QQ号/邮箱/MD5），例如：\n' +
        '/avatar/123456（QQ号）\n' +
        '/avatar/user@example.com（邮箱）',
        {
          status: 400,
          headers: { 'Content-Type': 'text/plain; charset=utf-8' }
        }
      )
    }
    
    // 1. 先判断是否为QQ号（5-13位数字）
    if (isValidQQ(param)) {
      return handleQQAvatar(param, url.searchParams)
    }
    
    // 2. 非QQ号则走原有Gravatar逻辑
    let md5Hash;
    if (isValidMD5(param)) {
      md5Hash = param.toLowerCase(); // MD5统一转小写
    } else {
      // 视为邮箱处理
      const processedEmail = param.trim().toLowerCase();
      md5Hash = await md5(processedEmail);
    }
    
    // 构建Gravatar URL
    const gravatarUrl = `https://www.gravatar.com/avatar/${md5Hash}${url.search}`
    return fetchAndProxy(gravatarUrl)
    
  } catch (error) {
    return new Response(
      `处理请求时出错: ${error.message}`,
      {
        status: 500,
        headers: { 'Content-Type': 'text/plain; charset=utf-8' }
      }
    )
  }
}

/**
 * 处理QQ头像代理
 * @param {string} qqNumber QQ号
 * @param {URLSearchParams} searchParams 查询参数（如size）
 */
async function handleQQAvatar(qqNumber, searchParams) {
  // QQ头像官方接口：https://q.qlogo.cn/g?b=qq&nk=QQ号&s=尺寸
  // 映射参数：将用户传入的size转换为s（默认尺寸100）
  const size = searchParams.get('size') || '100';
  // 构建QQ头像URL（保留其他可能的参数，如自定义头像参数）
  const qqAvatarUrl = new URL('https://q.qlogo.cn/g');
  qqAvatarUrl.searchParams.set('b', 'qq'); // 固定为qq标识
  qqAvatarUrl.searchParams.set('nk', qqNumber); // QQ号
  qqAvatarUrl.searchParams.set('s', size); // 尺寸
  // 透传其他参数（如用户可能传入的其他自定义参数）
  searchParams.forEach((value, key) => {
    if (!['size', 'b', 'nk', 's'].includes(key)) {
      qqAvatarUrl.searchParams.set(key, value);
    }
  });
  
  return fetchAndProxy(qqAvatarUrl.toString())
}

/**
 * 通用代理请求逻辑（复用Gravatar和QQ头像的响应处理）
 * @param {string} targetUrl 目标头像URL
 */
async function fetchAndProxy(targetUrl) {
  const response = await fetch(targetUrl, {
    method: 'GET',
    headers: {
      'User-Agent': 'EdgeOne Avatar Proxy',
      'Accept': 'image/*'
    },
    cache: 'default'
  });
  
  if (!response.ok) {
    return new Response(
      `获取头像失败: ${response.statusText}`,
      {
        status: response.status,
        headers: { 'Content-Type': 'text/plain; charset=utf-8' }
      }
    );
  }
  
  // 处理响应头（统一设置CORS、删除敏感头）
  const headers = new Headers(response.headers);
  headers.delete('access-control-allow-origin');
  headers.delete('set-cookie');
  headers.set('Access-Control-Allow-Origin', '*');
  headers.set('Access-Control-Allow-Methods', 'GET, OPTIONS');
  
  // 文本类型响应补全UTF-8编码
  const contentType = headers.get('Content-Type');
  if (contentType && contentType.startsWith('text/')) {
    headers.set('Content-Type', `${contentType}; charset=utf-8`);
  }
  
  return new Response(response.body, {
    status: response.status,
    headers
  });
}

/**
 * 验证是否为有效的QQ号（5-13位数字）
 * @param {string} str 待验证字符串
 * @returns {boolean}
 */
function isValidQQ(str) {
  const qqRegex = /^\d{5,13}$/; // QQ号为5-13位数字
  return qqRegex.test(str);
}

/**
 * 验证是否为有效的MD5（32位十六进制）
 * @param {string} str 待验证字符串
 * @returns {boolean}
 */
function isValidMD5(str) {
  const md5Regex = /^[0-9a-fA-F]{32}$/;
  return md5Regex.test(str);
}

/**
 * 计算字符串的MD5哈希（UTF-8编码）
 * @param {string} str 输入字符串
 * @returns {Promise<string>} 32位小写MD5
 */
async function md5(str) {
  const encoder = new TextEncoder();
  const data = encoder.encode(str);
  const digest = await crypto.subtle.digest('MD5', data);
  return Array.from(new Uint8Array(digest))
    .map(byte => byte.toString(16).padStart(2, '0'))
    .join('');
}