import type { Hono } from "hono";
import type { SessionStore } from "../session-store.js";
import { createLogger } from "../logger.js";

const log = createLogger("stats-routes");

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

export interface ModelBreakdown {
  model: string;
  count: number;
  cost: number;
}

export interface RecentSession {
  id: string;
  model: string;
  cost: number;
  turns: number;
  createdAt: number;
}

export interface StatsOverview {
  totalSessions: number;
  totalCost: number;
  totalTurns: number;
  modelBreakdown: ModelBreakdown[];
  recentSessions: RecentSession[];
}

// ─── Helpers ──────────────────────────────────────────────────────

/**
 * Extract the earliest user_message timestamp from a message history array.
 * Uses runtime checks to avoid issues with the BrowserIncomingMessage union type.
 */
function extractEarliestTimestamp(messages: unknown[] | undefined): number {
  if (!Array.isArray(messages) || messages.length === 0) return 0;
  for (const msg of messages) {
    if (
      msg != null &&
      typeof msg === "object" &&
      (msg as Record<string, unknown>).type === "user_message" &&
      typeof (msg as Record<string, unknown>).timestamp === "number"
    ) {
      return (msg as Record<string, unknown>).timestamp as number;
    }
  }
  return 0;
}

// ─── Routes ───────────────────────────────────────────────────────

export function registerStatsRoutes(api: Hono, sessionStore: SessionStore): void {
  api.get("/stats/overview", async (c) => {
    try {
      const allSessions = await sessionStore.loadAll();

      let totalCost = 0;
      let totalTurns = 0;
      const modelMap = new Map<string, { count: number; cost: number }>();
      const sessionSummaries: RecentSession[] = [];

      for (const session of allSessions) {
        const cost = session.state?.total_cost_usd ?? 0;
        const turns = session.state?.num_turns ?? 0;
        const model = session.state?.model ?? "unknown";

        totalCost += cost;
        totalTurns += turns;

        // Aggregate by model
        const existing = modelMap.get(model);
        if (existing) {
          existing.count += 1;
          existing.cost += cost;
        } else {
          modelMap.set(model, { count: 1, cost: cost });
        }

        // Derive creation timestamp from earliest user_message or fallback to 0
        // Cast to unknown[] to avoid TS union type issues with optional `timestamp` fields
        const createdAt = extractEarliestTimestamp(session.messageHistory as unknown[]);

        sessionSummaries.push({
          id: session.id,
          model,
          cost,
          turns,
          createdAt,
        });
      }

      // Build model breakdown sorted by cost descending
      const modelBreakdown: ModelBreakdown[] = Array.from(modelMap.entries())
        .map(([model, data]) => ({ model, count: data.count, cost: data.cost }))
        .sort((a, b) => b.cost - a.cost);

      // Recent sessions: last 10 by creation time
      sessionSummaries.sort((a, b) => b.createdAt - a.createdAt);
      const recentSessions = sessionSummaries.slice(0, 10);

      const overview: StatsOverview = {
        totalSessions: allSessions.length,
        totalCost,
        totalTurns,
        modelBreakdown,
        recentSessions,
      };

      return c.json(overview);
    } catch (err) {
      log.error({ err }, "Failed to compute stats overview");
      return c.json({ error: "Failed to compute stats overview" }, 500);
    }
  });
}
