/**
 * Achievement definitions and progress tracking logic.
 * Supports savings milestones, usage streaks, cache efficiency, and routing badges.
 */

import type { LucideIcon } from "lucide-react";
import { DollarSign, Flame, Zap, Route, Target } from "lucide-react";

export type AchievementCategory =
  | "savings"
  | "streak"
  | "cache"
  | "routing";

export interface AchievementDefinition {
  id: string;
  category: AchievementCategory;
  title: string;
  description: string;
  icon: LucideIcon;
  threshold: number;
  unit: "dollars" | "days" | "percent" | "count";
}

export interface UserProgress {
  savingsTotal: number;
  currentStreak: number;
  longestStreak: number;
  cacheHitRate: number;
  localRequests: number;
  totalRequests: number;
}

export interface AchievementWithProgress extends AchievementDefinition {
  progress: number;
  earned: boolean;
  earnedAt?: Date;
}

const SAVINGS_MILESTONES = [10, 50, 100, 500, 1000] as const;
const STREAK_MILESTONES = [7, 30, 90] as const;
const CACHE_MILESTONES = [50, 75, 90] as const;
const ROUTING_LOCAL = 1000;
const ROUTING_TOTAL = 10000;

export const ACHIEVEMENTS: AchievementDefinition[] = [
  ...SAVINGS_MILESTONES.map((amt) => ({
    id: `savings-${amt}`,
    category: "savings" as const,
    title: `$${amt} Saved`,
    description: `Reach $${amt} in total savings`,
    icon: DollarSign,
    threshold: amt,
    unit: "dollars" as const,
  })),
  ...STREAK_MILESTONES.map((days) => ({
    id: `streak-${days}`,
    category: "streak" as const,
    title: `${days}-Day Streak`,
    description: `Use LLMHosts ${days} days in a row`,
    icon: Flame,
    threshold: days,
    unit: "days" as const,
  })),
  ...CACHE_MILESTONES.map((pct) => ({
    id: `cache-${pct}`,
    category: "cache" as const,
    title: `${pct}% Cache Hit Rate`,
    description: `Achieve ${pct}% cache hit rate`,
    icon: Zap,
    threshold: pct,
    unit: "percent" as const,
  })),
  {
    id: "routing-local-1000",
    category: "routing",
    title: "1,000 Local Requests",
    description: "Route 1,000 requests to local models",
    icon: Route,
    threshold: ROUTING_LOCAL,
    unit: "count",
  },
  {
    id: "routing-total-10000",
    category: "routing",
    title: "10,000 Total Requests",
    description: "Handle 10,000 total requests",
    icon: Target,
    threshold: ROUTING_TOTAL,
    unit: "count",
  },
];

export function getRelevantValue(progress: UserProgress, def: AchievementDefinition): number {
  switch (def.category) {
    case "savings":
      return progress.savingsTotal;
    case "streak":
      return progress.longestStreak;
    case "cache":
      return progress.cacheHitRate;
    case "routing":
      if (def.id.includes("local")) return progress.localRequests;
      return progress.totalRequests;
    default:
      return 0;
  }
}

export function computeAchievementProgress(
  def: AchievementDefinition,
  progress: UserProgress,
): { progress: number; earned: boolean } {
  const value = getRelevantValue(progress, def);
  const pct = Math.min(100, (value / def.threshold) * 100);
  const earned = value >= def.threshold;
  return {
    progress: Math.round(pct * 100) / 100,
    earned,
  };
}

export function getAllAchievementsWithProgress(
  progress: UserProgress,
): AchievementWithProgress[] {
  return ACHIEVEMENTS.map((def) => {
    const { progress: pct, earned } = computeAchievementProgress(def, progress);
    return {
      ...def,
      progress: pct,
      earned,
    };
  });
}

export function groupAchievementsByCategory(
  items: AchievementWithProgress[],
): Record<AchievementCategory, AchievementWithProgress[]> {
  const groups: Record<AchievementCategory, AchievementWithProgress[]> = {
    savings: [],
    streak: [],
    cache: [],
    routing: [],
  };
  for (const item of items) {
    groups[item.category].push(item);
  }
  return groups;
}

/**
 * Generates a shareable URL for an achievement.
 * In a full implementation, this could encode achievement ID and user ID for a dedicated share page.
 */
export function getShareUrl(achievementId: string): string {
  if (typeof window === "undefined") {
    return `${process.env.NEXT_PUBLIC_APP_URL || ""}/dashboard/achievements?share=${achievementId}`;
  }
  const base = window.location.origin;
  return `${base}/dashboard/achievements?share=${achievementId}`;
}
