// Anthropic (Claude) provider — analysis only.
//
// Claude does not natively transcribe audio, so transcribeAudio() throws.
// Mix-and-match users can pair this provider for analysis with Gemini
// (or future OpenAI Whisper) for transcription.
//
// Pricing reflects standard-context rates as of 2026-04-29 (cached in
// the claude-api skill). Update when Anthropic changes published rates.

import Anthropic from "@anthropic-ai/sdk";
import { retryAPI } from "../util.js";
import { formatCost, ratesFor } from "./cost.js";

// Per-1M-token rates in USD. Anthropic does not expose a separate
// "thinking" rate — thinking tokens are billed as output, so we let
// formatCost default thinking → output by omitting the thinking field.
export const ANTHROPIC_PRICING = {
  "claude-opus-4-7":   { input: 5.00, output: 25.00 },
  "claude-opus-4-6":   { input: 5.00, output: 25.00 },
  "claude-sonnet-4-6": { input: 3.00, output: 15.00 },
  "claude-haiku-4-5":  { input: 1.00, output: 5.00 },
  // Fallback for unknown / future models.
  "default":           { input: 3.00, output: 15.00 },
};

// Analysis model list. Order = default fallback chain (most capable first).
export const ANTHROPIC_ANALYSIS_MODELS = [
  "claude-opus-4-7",
  "claude-opus-4-6",
  "claude-sonnet-4-6",
  "claude-haiku-4-5",
];

// Analysis output cap. Generous — the topic-analysis prompt produces a
// JSON document scaled to transcript length, and truncation here loses
// trailing sections.
const ANALYSIS_MAX_TOKENS = 16000;

export function createAnthropicProvider({ apiKey, timeoutMs = 900_000 } = {}) {
  if (!apiKey) {
    throw new Error("createAnthropicProvider: apiKey is required");
  }
  const client = new Anthropic({ apiKey, timeout: timeoutMs });

  return {
    name: "anthropic",

    capabilities: {
      transcribe: false,
      analyze: true,
      listModels: true,
    },

    listAnalysisModels() {
      return [...ANTHROPIC_ANALYSIS_MODELS];
    },

    listTranscriptionModels() {
      return [];
    },

    async transcribeAudio() {
      throw new Error(
        "Anthropic models do not natively transcribe audio. Use Gemini or OpenAI (Whisper) for the transcription step."
      );
    },

    async analyzeText({
      prompt,
      model,
      onProgress = () => {},
      retries = 2,
      signal,
    }) {
      const result = await retryAPI(
        () =>
          client.messages.create(
            {
              model,
              max_tokens: ANALYSIS_MAX_TOKENS,
              messages: [{ role: "user", content: prompt }],
            },
            // The Anthropic SDK accepts a per-call signal as the second
            // arg; abort() rejects the in-flight HTTP request immediately.
            signal ? { signal } : undefined
          ),
        {
          retries,
          delayMs: 5000,
          label: "Anthropic analysis",
          log: (msg) => onProgress(msg),
        }
      );

      const text = (result.content || [])
        .filter((b) => b.type === "text")
        .map((b) => b.text)
        .join("");

      const usage = {
        inputTokens: result.usage?.input_tokens || 0,
        outputTokens: result.usage?.output_tokens || 0,
        thinkingTokens: 0,
      };
      const cost = formatCost(ratesFor(ANTHROPIC_PRICING, model), usage);

      return {
        text,
        usage,
        cost,
        finishReason: result.stop_reason || null,
        raw: result,
      };
    },
  };
}
