// ============================================================
// rollout.ts — 灰度发布用户分组工具
//
// 用途：
//   1. 为每个用户生成稳定的分组哈希（同一用户始终在同一组）
//   2. 根据服务端返回的放量百分比判断当前用户是否在放量范围内
//   3. 支持渠道（stable/beta/alpha）+ 百分比放量组合
//
// 核心算法：
//   - 将 deviceId + version + channel 拼接后取 SHA-256 前 8 位
//   - 转为 0–100 的整数（即百分比桶）
//   - 与后端下发的 rolloutPercent 比较
//
// 服务端 API 需返回：
//   {
//     channel: "beta",
//     rolloutPercent: 30,     // 0–100，0 表示暂停放量，100 表示全量
//     ...
//   }
//
// 客户端逻辑：
//   if (isInRolloutGroup(deviceId, version, channel, rolloutPercent)) {
//     // 命中灰度 → 使用此版本
//   } else {
//     // 未命中 → 检查 stable 渠道
//   }
// ============================================================

/**
 * 计算用户的灰度分组值（0–99 的稳定整数）。
 * 同一 deviceId + version + channel 始终返回同一值。
 */
export function getRolloutGroup(
  deviceId: string,
  version: string,
  channel: string,
): number {
  // 使用简单的 DJB2 哈希（确定性，跨平台一致，无需 crypto API）
  const input = `${deviceId}:${version}:${channel}`;
  let hash = 5381;
  for (let i = 0; i < input.length; i++) {
    hash = ((hash << 5) + hash + input.charCodeAt(i)) & 0xffffffff;
  }
  // 映射到 0–99
  return Math.abs(hash) % 100;
}

/**
 * 判断当前用户是否在灰度放量范围内。
 *
 * @param deviceId  设备唯一标识
 * @param version   目标版本号
 * @param channel   发布渠道
 * @param rolloutPercent  放量百分比（0–100，0 = 暂停，100 = 全量）
 * @returns true 表示该用户应收到此版本更新
 */
export function isInRolloutGroup(
  deviceId: string,
  version: string,
  channel: string,
  rolloutPercent: number,
): boolean {
  if (rolloutPercent <= 0) return false;
  if (rolloutPercent >= 100) return true;
  return getRolloutGroup(deviceId, version, channel) < rolloutPercent;
}

/**
 * 设备 ID 生成（UUID v4），持久化到 localStorage。
 * 首次调用生成，后续调用返回已有值。
 */
export function getDeviceId(): string {
  const STORAGE_KEY = 'heixiu:device-id';

  try {
    const cached = localStorage.getItem(STORAGE_KEY);
    if (cached) return cached;

    // UUID v4
    const uuid = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, (c) => {
      const r = (Math.random() * 16) | 0;
      const v = c === 'x' ? r : (r & 0x3) | 0x8;
      return v.toString(16);
    });

    localStorage.setItem(STORAGE_KEY, uuid);
    return uuid;
  } catch {
    // localStorage 不可用（如隐私模式）— 返回临时 ID
    return `temp-${Date.now()}-${Math.random().toString(36).slice(2, 9)}`;
  }
}

// ============================================================
// 类型定义（与服务端 API 对齐）
// ============================================================

/** 服务端返回的更新信息（含灰度放量配置） */
export interface RolloutUpdateInfo {
  hasUpdate: boolean;
  latestVersion: string;
  downloadUrl: string;
  fileSize: number;
  sha512: string;
  changelog: string;
  releaseDate: string;
  forceUpdate: boolean;
  minimumVersion: string;
  blockMapUrl?: string;
  blockMapSize?: number;

  /** 发布渠道 */
  channel: 'stable' | 'beta' | 'alpha';
  /** 放量百分比（0–100，100 = 全量） */
  rolloutPercent: number;
}

/** 构建时注入的渠道信息（由 Vite 环境变量提供） */
export interface BuildChannelInfo {
  /** 当前客户端渠道 */
  channel: 'stable' | 'beta' | 'alpha';
  /** 构建版本号 */
  version: string;
  /** Git commit 短哈希 */
  commit?: string;
  /** 构建时间戳 */
  timestamp?: string;
}

/**
 * 读取构建时注入的渠道信息。
 * 这些值由 build.mjs 通过 Vite 环境变量注入。
 */
export function getBuildChannelInfo(): BuildChannelInfo {
  return {
    channel: (import.meta.env.VITE_BUILD_CHANNEL as 'stable' | 'beta' | 'alpha') || 'stable',
    version: (import.meta.env.VITE_BUILD_VERSION as string) || '0.0.0',
    commit: import.meta.env.VITE_BUILD_COMMIT as string | undefined,
    timestamp: import.meta.env.VITE_BUILD_TIMESTAMP as string | undefined,
  };
}
