/**
 * 绩效进度条共用模块 -- task-list / coach-detail 统一使用
 *
 * 包含：动画参数、刻度计算、高光时长计算、类型定义
 */

/* ======================================================
 *           进度条动画参数 -- 在此调节
 * ======================================================
 *
 * 动画由 JS 状态机驱动，每轮循环重新读取实际进度条宽度：
 *
 *  +-------------+  SPARK_DELAY_MS  +-------------+  NEXT_LOOP_DELAY_MS  +-------------+
 *  | 高光匀速扫过 | --------------> |  火花迸发    | ------------------> |  下一轮      |
 *  | 时长由速度决定|                 | SPARK_DUR_MS|                     |(重新读进度)  |
 *  +-------------+                 +-------------+                     +-------------+
 *
 *  SHINE_SPEED      : 高光移动速度，范围 1~100
 *                     1   = 最慢，最宽进度条(100%)下 5 秒走完
 *                     100 = 最快，最宽进度条(100%)下 0.05 秒走完
 *                     实际时长 = 基准时长 x (filledPct/100)
 *                     基准时长 = 5s - (SHINE_SPEED-1)/(100-1) x (5-0.05)s
 *
 *  SPARK_DELAY_MS   : 高光到达最右端后，光柱点亮+火花迸发的延迟(毫秒)
 *                     正数 = 高光结束后停顿再点亮
 *                     负数 = 高光还未结束，提前点亮(高光末尾与火花重叠)
 *
 *  SPARK_DUR_MS     : 火花迸发到完全消散的时长(毫秒)
 *
 *  NEXT_LOOP_DELAY_MS: 火花消散后到下一轮高光启动的延迟(毫秒)
 *                      正数 = 停顿一段时间
 *                      负数 = 火花还未消散完，高光已从左端启动
 *
 * 修改说明见 apps/miniprogram/doc/progress-bar-animation.md
 */
export const SHINE_SPEED         = 70    // 1~100，速度值
export const SPARK_DELAY_MS      = -200  // 毫秒，高光结束->光柱点亮+火花(负=提前)
export const SPARK_DUR_MS        = 1400  // 毫秒，火花持续时长
export const NEXT_LOOP_DELAY_MS  = 400   // 毫秒，火花结束->下轮高光(负=提前)

/* 高光宽度固定(SHINE_WIDTH_RPX)，需要走过的距离 = 填充条宽度 + 高光宽度
 * 轨道宽度约 634rpx(750 - 左右padding各58rpx)，高光宽度约占轨道 19%
 * 时长正比于需要走过的总距离，保证视觉速度恒定
 *
 * 速度1  -> baseDur=5000ms(最慢)，速度100 -> baseDur=50ms(最快)
 * shineDurMs = baseDur x (filledPct + SHINE_WIDTH_PCT) / (100 + SHINE_WIDTH_PCT)
 */
export const SHINE_WIDTH_RPX  = 120  // rpx，需与 WXSS 的 --shine-width 保持一致
export const TRACK_WIDTH_RPX  = 634  // rpx，进度条轨道宽度(750 - padding 116rpx)
export const SHINE_WIDTH_PCT  = (SHINE_WIDTH_RPX / TRACK_WIDTH_RPX) * 100  // ~19%

// ── 类型定义 ────────────────────────────────────────────────

/** 刻度项（传给 perf-progress-bar 组件的 ticks 属性） */
export interface TickItem {
  value: number     // 刻度数值（如 100）
  label: string     // 显示文字（如 '100'）
  left: string      // 百分比位置字符串（如 '45.45%'），首尾项忽略此字段
  highlight: boolean // 是否加粗高亮
}

// ── 工具函数 ────────────────────────────────────────────────

/**
 * 根据速度值和进度百分比计算高光扫过时长。
 *
 * 速度 1 -> baseDur=5000ms（最慢），速度 100 -> baseDur=50ms（最快）
 * 实际时长 = baseDur x (filledPct + SHINE_WIDTH_PCT) / (100 + SHINE_WIDTH_PCT)
 */
export function calcShineDur(filledPct: number): number {
  const t = (SHINE_SPEED - 1) / 99  // 0(最慢) ~ 1(最快)
  const baseDur = 5000 - t * (5000 - 50)
  const distRatio = (filledPct + SHINE_WIDTH_PCT) / (100 + SHINE_WIDTH_PCT)
  return Math.max(50, Math.round(baseDur * distRatio))
}

/**
 * 根据档位节点数组生成刻度数据（供 perf-progress-bar 组件渲染）。
 */
export function buildTicks(tierNodes: number[], maxHours: number): TickItem[] {
  return tierNodes.map((v, i) => ({
    value: v,
    label: String(v),
    left: `${Math.round((v / maxHours) * 10000) / 100}%`,
    highlight: false,
  }))
}

/**
 * 从后端返回的 performance 对象中计算进度条所需的全部数据。
 *
 * 两个页面统一调用此函数，确保进度百分比、当前档位、刻度等计算逻辑一致。
 */
export function buildProgressBarData(perf: Record<string, any>) {
  // 后端返回 snake_case（CamelModel 可能已转 camelCase），兼容两种命名
  const totalHours = perf.totalHours ?? perf.total_hours ?? 0
  const tierNodes: number[] = perf.tierNodes ?? perf.tier_nodes ?? [0]
  const currentTier = perf.currentTier ?? perf.current_tier ?? 0
  const nextTierHours = perf.nextTierHours ?? perf.next_tier_hours ?? 0

  const maxHours = tierNodes.length > 0 ? tierNodes[tierNodes.length - 1] : 0
  const filledPct = maxHours > 0 ? Math.min(100, Math.round((totalHours / maxHours) * 1000) / 10) : 0
  const clampedSparkPct = Math.max(0, Math.min(100, filledPct))
  const remainHours = Math.max(0, nextTierHours - totalHours)
  const ticks = buildTicks(tierNodes, maxHours)

  // 段内进度（当前档位内的百分比）
  const segStart = tierNodes[currentTier] ?? 0
  const segEnd = tierNodes[currentTier + 1] ?? maxHours
  const tierProgress = segEnd > segStart
    ? Math.min(100, Math.round(((totalHours - segStart) / (segEnd - segStart)) * 100))
    : 100

  return {
    filledPct,
    clampedSparkPct,
    currentTier,
    ticks,
    remainHours,
    tierProgress,
    shineDurMs: calcShineDur(filledPct),
    sparkDurMs: SPARK_DUR_MS,
  }
}
