/**
 * Token usage profile builder.
 *
 * Builds a usage profile from the user's historical costs and usage patterns
 * so Token can provide personalized recommendations and savings insights.
 */

interface UsageRecord {
  model: string;
  provider: string;
  tokensIn: number;
  tokensOut: number;
  cost: number;
  timestamp: Date;
  isLocal: boolean;
}

interface UsageProfile {
  /** Most-used models ranked by request count */
  topModels: Array<{ model: string; count: number; totalCost: number }>;
  /** Average daily spend (cloud APIs) */
  avgDailySpend: number;
  /** Percentage of requests served locally */
  localPercentage: number;
  /** Total tokens processed */
  totalTokens: number;
  /** Cloud cost savings from local inference */
  estimatedSavings: number;
  /** Peak usage hours (0-23) */
  peakHours: number[];
  /** Usage trend: increasing, stable, or decreasing */
  trend: "increasing" | "stable" | "decreasing";
}

/**
 * Build a usage profile from historical records.
 */
export function buildUsageProfile(records: UsageRecord[]): UsageProfile {
  if (records.length === 0) {
    return {
      topModels: [],
      avgDailySpend: 0,
      localPercentage: 0,
      totalTokens: 0,
      estimatedSavings: 0,
      peakHours: [],
      trend: "stable",
    };
  }

  // Model usage counts
  const modelMap = new Map<string, { count: number; totalCost: number }>();
  for (const r of records) {
    const existing = modelMap.get(r.model) || { count: 0, totalCost: 0 };
    existing.count += 1;
    existing.totalCost += r.cost;
    modelMap.set(r.model, existing);
  }
  const topModels = Array.from(modelMap.entries())
    .map(([model, stats]) => ({ model, ...stats }))
    .sort((a, b) => b.count - a.count)
    .slice(0, 5);

  // Daily spend
  const cloudRecords = records.filter((r) => !r.isLocal);
  const days = new Set(records.map((r) => r.timestamp.toISOString().slice(0, 10)));
  const avgDailySpend =
    days.size > 0 ? cloudRecords.reduce((sum, r) => sum + r.cost, 0) / days.size : 0;

  // Local percentage
  const localCount = records.filter((r) => r.isLocal).length;
  const localPercentage = (localCount / records.length) * 100;

  // Total tokens
  const totalTokens = records.reduce((sum, r) => sum + r.tokensIn + r.tokensOut, 0);

  // Estimated savings (local requests that would have cost cloud prices)
  // Rough estimate: average cloud cost per request * local request count
  const avgCloudCost =
    cloudRecords.length > 0
      ? cloudRecords.reduce((sum, r) => sum + r.cost, 0) / cloudRecords.length
      : 0.002; // default $0.002 per request
  const estimatedSavings = localCount * avgCloudCost;

  // Peak hours
  const hourCounts = new Map<number, number>();
  for (const r of records) {
    const hour = r.timestamp.getHours();
    hourCounts.set(hour, (hourCounts.get(hour) || 0) + 1);
  }
  const maxCount = Math.max(...hourCounts.values(), 0);
  const threshold = maxCount * 0.7;
  const peakHours = Array.from(hourCounts.entries())
    .filter(([, count]) => count >= threshold)
    .map(([hour]) => hour)
    .sort((a, b) => a - b);

  // Trend (compare first half vs second half)
  const mid = Math.floor(records.length / 2);
  const firstHalf = records.slice(0, mid);
  const secondHalf = records.slice(mid);
  const firstAvg =
    firstHalf.length > 0
      ? firstHalf.reduce((sum, r) => sum + r.tokensIn + r.tokensOut, 0) / firstHalf.length
      : 0;
  const secondAvg =
    secondHalf.length > 0
      ? secondHalf.reduce((sum, r) => sum + r.tokensIn + r.tokensOut, 0) / secondHalf.length
      : 0;

  let trend: "increasing" | "stable" | "decreasing" = "stable";
  if (secondAvg > firstAvg * 1.2) trend = "increasing";
  else if (secondAvg < firstAvg * 0.8) trend = "decreasing";

  return {
    topModels,
    avgDailySpend,
    localPercentage,
    totalTokens,
    estimatedSavings,
    peakHours,
    trend,
  };
}

/**
 * Format usage profile as a system prompt section.
 */
export function formatUsagePrompt(profile: UsageProfile): string {
  if (profile.topModels.length === 0) {
    return "## Usage Profile\nNo usage data yet. This user is new — help them get started.";
  }

  const lines = ["## Usage Profile"];
  lines.push(`- Total tokens processed: ${profile.totalTokens.toLocaleString()}`);
  lines.push(`- Local inference: ${profile.localPercentage.toFixed(0)}% of requests`);
  lines.push(`- Average daily cloud spend: $${profile.avgDailySpend.toFixed(2)}`);
  lines.push(`- Estimated savings from local: $${profile.estimatedSavings.toFixed(2)}`);
  lines.push(`- Usage trend: ${profile.trend}`);

  if (profile.topModels.length > 0) {
    lines.push("\n### Most-Used Models");
    for (const m of profile.topModels) {
      lines.push(`- ${m.model}: ${m.count} requests ($${m.totalCost.toFixed(2)})`);
    }
  }

  if (profile.peakHours.length > 0) {
    lines.push(`\n### Peak Hours: ${profile.peakHours.map((h) => `${h}:00`).join(", ")}`);
  }

  return lines.join("\n");
}

export type { UsageRecord, UsageProfile };
