/**
 * Cookie编码处理工具
 * 解决特殊字符在Cookie中的编码问题
 */

/**
 * 安全编码Cookie值
 * 使用encodeURIComponent确保特殊字符正确编码
 *
 * @param value 原始值
 * @returns 编码后的值
 */
export function encodeCookieValue(value: string): string {
  if (!value) return '';

  try {
    // 使用encodeURIComponent编码所有特殊字符
    return encodeURIComponent(value);
  } catch (error) {
    console.error('Cookie值编码失败:', error);
    return value; // 编码失败时返回原值
  }
}

/**
 * 安全解码Cookie值
 * 使用decodeURIComponent解码编码的值
 *
 * @param encodedValue 编码后的值
 * @returns 解码后的原始值
 */
export function decodeCookieValue(encodedValue: string): string {
  if (!encodedValue) return '';

  try {
    // 使用decodeURIComponent解码
    return decodeURIComponent(encodedValue);
  } catch (error) {
    console.error('Cookie值解码失败:', error);
    // 解码失败时，可能值已经未编码，返回原值
    return encodedValue;
  }
}

/**
 * 批量编码Cookie对象中的所有值
 *
 * @param cookieObj Cookie对象 {key: value}
 * @returns 编码后的Cookie对象
 */
export function encodeCookieObject(cookieObj: Record<string, string>): Record<string, string> {
  const encoded: Record<string, string> = {};

  for (const [key, value] of Object.entries(cookieObj)) {
    encoded[key] = encodeCookieValue(value);
  }

  return encoded;
}

/**
 * 批量解码Cookie对象中的所有值
 *
 * @param encodedCookieObj 编码的Cookie对象
 * @returns 解码后的Cookie对象
 */
export function decodeCookieObject(encodedCookieObj: Record<string, string>): Record<string, string> {
  const decoded: Record<string, string> = {};

  for (const [key, value] of Object.entries(encodedCookieObj)) {
    decoded[key] = decodeCookieValue(value);
  }

  return decoded;
}

/**
 * 安全解析包含编码值的Cookie字符串
 *
 * @param cookieString Cookie字符串
 * @returns 解析后的Cookie对象
 */
export function parseEncodedCookieString(cookieString: string): Record<string, string> {
  if (!cookieString) return {};

  const cookies: Record<string, string> = {};

  // 分割多个Cookie对
  const cookiePairs = cookieString.split(';').map(pair => pair.trim());

  for (const pair of cookiePairs) {
    if (!pair) continue;

    const [key, ...valueParts] = pair.split('=');
    if (!key) continue;

    const value = valueParts.join('=');
    cookies[key] = decodeCookieValue(value);
  }

  return cookies;
}

/**
 * 创建包含编码值的Cookie字符串
 *
 * @param cookieObj Cookie对象
 * @returns 编码后的Cookie字符串
 */
export function createEncodedCookieString(cookieObj: Record<string, string>): string {
  const encodedPairs: string[] = [];

  for (const [key, value] of Object.entries(cookieObj)) {
    const encodedValue = encodeCookieValue(value);
    encodedPairs.push(`${key}=${encodedValue}`);
  }

  return encodedPairs.join('; ');
}

/**
 * 检查字符串是否包含特殊字符
 *
 * @param value 要检查的字符串
 * @returns 是否包含需要编码的字符
 */
export function hasSpecialChars(value: string): boolean {
  // 检查是否包含需要编码的特殊字符
  const specialChars = /[^\w\-._~!$&'()*+,;=:@\/]/;
  return specialChars.test(value);
}

/**
 * 智能编码：仅对包含特殊字符的值进行编码
 *
 * @param value 要编码的值
 * @returns 编码后的值
 */
export function smartEncodeCookieValue(value: string): string {
  if (!value) return '';

  // 如果包含特殊字符则编码，否则返回原值
  return hasSpecialChars(value) ? encodeCookieValue(value) : value;
}

/**
 * 智能解码：尝试解码，失败则返回原值
 *
 * @param encodedValue 可能编码的值
 * @returns 解码后的值
 */
export function smartDecodeCookieValue(encodedValue: string): string {
  if (!encodedValue) return '';

  // 尝试解码，如果解码后的值与原值相同，可能说明没有编码过
  try {
    const decoded = decodeCookieValue(encodedValue);
    return decoded;
  } catch (error) {
    return encodedValue;
  }
}