import type { JsonValue } from "agentlens-sdk";

export function truncate(str: string, maxLength: number): string {
  if (str.length <= maxLength) return str;
  return str.slice(0, maxLength) + "... [truncated]";
}

export function extractToolMetadata(
  tool: string,
  args: unknown,
): Record<string, unknown> {
  const a = args as Record<string, unknown> | null | undefined;
  if (!a || typeof a !== "object") return {};

  switch (tool) {
    case "read":
    case "mcp_read":
      return { filePath: a["filePath"] };

    case "write":
    case "mcp_write":
      return { filePath: a["filePath"] };

    case "edit":
    case "mcp_edit":
      return { filePath: a["filePath"] };

    case "bash":
    case "mcp_bash":
      return {
        command: truncate(String(a["command"] ?? ""), 200),
      };

    case "glob":
    case "mcp_glob":
      return { pattern: a["pattern"] };

    case "grep":
    case "mcp_grep":
      return { pattern: a["pattern"], path: a["path"] };

    case "task":
    case "mcp_task":
      return {
        category: a["category"],
        description: a["description"],
      };

    default:
      return {};
  }
}

const MODEL_COSTS: Record<string, { input: number; output: number }> = {
  "gpt-5.2": { input: 1.75, output: 14 },
  "gpt-5.1": { input: 1.25, output: 10 },
  "gpt-5": { input: 1.25, output: 10 },
  "gpt-5-mini": { input: 0.25, output: 2 },
  "gpt-5-nano": { input: 0.05, output: 0.4 },
  "gpt-4.1": { input: 2, output: 8 },
  "gpt-4.1-mini": { input: 0.4, output: 1.6 },
  "gpt-4.1-nano": { input: 0.1, output: 0.4 },
  "o3": { input: 2, output: 8 },
  "o3-mini": { input: 1.1, output: 4.4 },
  "o4-mini": { input: 1.1, output: 4.4 },
  "o1": { input: 15, output: 60 },
  "gpt-4o": { input: 2.5, output: 10 },
  "gpt-4o-mini": { input: 0.15, output: 0.6 },
  "gpt-4-turbo": { input: 10, output: 30 },
  "gpt-4": { input: 30, output: 60 },
  "claude-opus-4-6": { input: 5, output: 25 },
  "claude-opus-4-20250514": { input: 15, output: 75 },
  "claude-sonnet-4-20250514": { input: 3, output: 15 },
  "claude-4.5-opus": { input: 5, output: 25 },
  "claude-4.5-sonnet": { input: 3, output: 15 },
  "claude-4.5-haiku": { input: 1, output: 5 },
  "claude-3-5-sonnet": { input: 3, output: 15 },
  "claude-3-5-haiku": { input: 0.8, output: 4 },
  "claude-3-opus": { input: 15, output: 75 },
  "claude-3-haiku": { input: 0.25, output: 1.25 },
};

export function getModelCost(
  modelId: string,
): { input: number; output: number } | undefined {
  const direct = MODEL_COSTS[modelId];
  if (direct) return direct;

  for (const [key, cost] of Object.entries(MODEL_COSTS)) {
    if (modelId.includes(key)) return cost;
  }
  return undefined;
}

/** Coerce arbitrary values into SDK-compatible `JsonValue`, stringifying unknowns. */
export function safeJsonValue(value: unknown): JsonValue {
  if (value === null || value === undefined) return null;
  if (
    typeof value === "string" ||
    typeof value === "number" ||
    typeof value === "boolean"
  ) {
    return value;
  }
  if (Array.isArray(value)) {
    return value.map((v) => safeJsonValue(v));
  }
  if (typeof value === "object") {
    const result: Record<string, JsonValue> = {};
    for (const [k, v] of Object.entries(value as Record<string, unknown>)) {
      result[k] = safeJsonValue(v);
    }
    return result;
  }
  return String(value);
}
