/**
 * Telemetry API Client
 * Handles telemetry data fetching for the usage dashboard.
 */

import { apiGet, type ApiResponse } from "./client";

// ─── Types ───────────────────────────────────────────────────────────

export type TimeRange = "7d" | "30d" | "90d";

export interface UsageSummary {
  totalTokens: number;
  totalCost: number;
  taskCount: number;
  avgQualityGatePassRate: number;
}

export interface TokenUsagePoint {
  date: string;
  inputTokens: number;
  outputTokens: number;
  totalTokens: number;
}

export interface CostBreakdownItem {
  model: string;
  provider: string;
  cost: number;
  taskCount: number;
}

export interface TaskOutcomeItem {
  outcome: string;
  count: number;
  color: string;
}

export interface EstimateParams {
  taskType: string;
  model: string;
  provider: string;
  complexity: string;
}

export interface EstimateResponse {
  prediction: {
    input_tokens: { median: number; p75: number; p90: number };
    output_tokens: { median: number; p75: number; p90: number };
    cost_usd_micros: Record<string, number>;
    quality: { gate_pass_rate: number; success_rate: number };
  } | null;
  metadata: {
    sample_size: number;
    confidence: "none" | "low" | "medium" | "high";
  };
}

interface ProviderUsageAnalyticsItem {
  provider: string;
  calls: number;
  promptTokens: number;
  completionTokens: number;
  totalTokens: number;
  costCents: number;
  averageDurationMs: number;
}

interface ModelUsageAnalyticsItem {
  model: string;
  calls: number;
  promptTokens: number;
  completionTokens: number;
  totalTokens: number;
  costCents: number;
  averageDurationMs: number;
}

interface TaskTypeUsageAnalyticsItem {
  taskType: string;
  calls: number;
  promptTokens: number;
  completionTokens: number;
  totalTokens: number;
  costCents: number;
  averageDurationMs: number;
}

interface UsageAnalyticsResponse {
  totalCalls: number;
  totalPromptTokens: number;
  totalCompletionTokens: number;
  totalTokens: number;
  totalCostCents: number;
  averageDurationMs: number;
  byProvider: ProviderUsageAnalyticsItem[];
  byModel: ModelUsageAnalyticsItem[];
  byTaskType: TaskTypeUsageAnalyticsItem[];
}

const TASK_OUTCOME_COLORS = ["#6EBF8B", "#F5C862", "#94A3B8", "#C4A5DE", "#7AA2F7"];
const DAYS_BY_RANGE: Record<TimeRange, number> = {
  "7d": 7,
  "30d": 30,
  "90d": 90,
};
const analyticsRequestCache = new Map<TimeRange, Promise<UsageAnalyticsResponse>>();

function buildAnalyticsEndpoint(timeRange: TimeRange): string {
  const endDate = new Date();
  const startDate = new Date(endDate);
  startDate.setDate(startDate.getDate() - (DAYS_BY_RANGE[timeRange] - 1));
  startDate.setHours(0, 0, 0, 0);

  const query = new URLSearchParams({
    startDate: startDate.toISOString(),
    endDate: endDate.toISOString(),
  }).toString();

  return `/api/llm-usage/analytics?${query}`;
}

async function fetchUsageAnalytics(timeRange: TimeRange): Promise<UsageAnalyticsResponse> {
  const cachedRequest = analyticsRequestCache.get(timeRange);
  if (cachedRequest) {
    return cachedRequest;
  }

  const request = apiGet<ApiResponse<UsageAnalyticsResponse>>(buildAnalyticsEndpoint(timeRange))
    .then((response) => response.data)
    .finally(() => {
      analyticsRequestCache.delete(timeRange);
    });

  analyticsRequestCache.set(timeRange, request);
  return request;
}

// ─── API Functions ───────────────────────────────────────────────────

/**
 * Fetch usage summary data (total tokens, cost, task count, quality rate)
 */
export async function fetchUsageSummary(timeRange: TimeRange): Promise<UsageSummary> {
  const analytics = await fetchUsageAnalytics(timeRange);

  return {
    totalTokens: analytics.totalTokens,
    totalCost: analytics.totalCostCents / 100,
    taskCount: analytics.totalCalls,
    avgQualityGatePassRate: 0,
  };
}

/**
 * Fetch token usage time series for charts
 */
export function fetchTokenUsage(timeRange: TimeRange): Promise<TokenUsagePoint[]> {
  void timeRange;
  return Promise.resolve([]);
}

/**
 * Fetch cost breakdown by model
 */
export async function fetchCostBreakdown(timeRange: TimeRange): Promise<CostBreakdownItem[]> {
  const analytics = await fetchUsageAnalytics(timeRange);

  return analytics.byModel
    .filter((item) => item.calls > 0)
    .sort((a, b) => b.costCents - a.costCents)
    .map((item) => ({
      model: item.model,
      provider: "unknown",
      cost: item.costCents / 100,
      taskCount: item.calls,
    }));
}

/**
 * Fetch task outcome distribution
 */
export async function fetchTaskOutcomes(timeRange: TimeRange): Promise<TaskOutcomeItem[]> {
  const analytics = await fetchUsageAnalytics(timeRange);

  return analytics.byTaskType
    .filter((item) => item.calls > 0)
    .map((item, index) => ({
      outcome: item.taskType,
      count: item.calls,
      color: TASK_OUTCOME_COLORS[index % TASK_OUTCOME_COLORS.length] ?? "#94A3B8",
    }));
}

/**
 * Fetch cost/token estimate for a given task configuration.
 * Uses the real GET /api/telemetry/estimate endpoint from TEL-006.
 */
export async function fetchEstimate(params: EstimateParams): Promise<EstimateResponse> {
  const query = new URLSearchParams({
    taskType: params.taskType,
    model: params.model,
    provider: params.provider,
    complexity: params.complexity,
  }).toString();

  const response = await apiGet<ApiResponse<EstimateResponse>>(`/api/telemetry/estimate?${query}`);
  return response.data;
}
