/**
 * Marketplace device reputation score (Phase 5, issue 290).
 *
 * MVP formula: 50 (base) + online bonus (25 if online and recent) + latency bonus
 * (25 if <100ms, 10 if <500ms). Range 50–100 when we have status/latency; offline
 * or stale lastSeen removes online bonus (max 75). No P95/success-rate history yet.
 *
 * Staleness: lastSeen older than STALE_MS is treated as not "recent" (no online bonus).
 */

export const STALE_MS = 5 * 60 * 1000; // 5 minutes

/**
 * Compute 0–100 reputation score from device status, latency, and lastSeen.
 * Online + recent + low latency => up to 100; offline or stale => no online bonus.
 */
export function computeReputationScore(
  status: string,
  latencyMs: number | null | undefined,
  lastSeen: Date | string
): number {
  const now = Date.now();
  const lastSeenTime = typeof lastSeen === "string" ? new Date(lastSeen).getTime() : lastSeen.getTime();
  const recent = now - lastSeenTime <= STALE_MS;
  const online = (status || "").toLowerCase() === "online";
  const onlineBonus = online && recent ? 25 : 0;

  const latency = latencyMs == null ? null : Number(latencyMs);
  let latencyBonus = 0;
  if (latency !== null && !Number.isNaN(latency)) {
    if (latency < 100) latencyBonus = 25;
    else if (latency < 500) latencyBonus = 10;
  }

  const score = 50 + onlineBonus + latencyBonus;
  return Math.min(100, Math.max(0, score));
}

/** Reputation tiers (Phase 5B, issue #308). */
export const REPUTATION_TIER_UNVERIFIED = "Unverified";
export const REPUTATION_TIER_STANDARD = "Standard";
export const REPUTATION_TIER_VERIFIED = "Verified";
export const REPUTATION_TIER_ELITE = "Elite";

/**
 * Map 0-100 score to tier: Unverified (<50), Standard (50-79), Verified (80-94), Elite (95-100).
 */
export function reputationTier(score: number): string {
  const s = Math.round(score);
  if (s < 50) return REPUTATION_TIER_UNVERIFIED;
  if (s < 80) return REPUTATION_TIER_STANDARD;
  if (s < 95) return REPUTATION_TIER_VERIFIED;
  return REPUTATION_TIER_ELITE;
}

/**
 * Final 0-100 score blending base reputation with 30d uptime when available (Phase 5B).
 * Formula: 0.6 * baseScore + 0.4 * uptimePct. When uptimePct is null, returns baseScore.
 */
export function reputationScoreWithUptime(
  baseScore: number,
  uptimePct: number | null | undefined
): number {
  if (uptimePct == null || Number.isNaN(uptimePct)) return baseScore;
  const blended = 0.6 * baseScore + 0.4 * uptimePct;
  return Math.min(100, Math.max(0, Math.round(blended)));
}
