import Anthropic from "@anthropic-ai/sdk";
import type { MetadataResult, ScriptResult, SourceMeta, ThemeBrief } from "./types";

const MODEL = "claude-sonnet-5";

function getClient(): Anthropic {
  const apiKey = process.env.ANTHROPIC_API_KEY;
  if (!apiKey) {
    throw new Error("ANTHROPIC_API_KEY is not set — add it to .env to generate real content.");
  }
  return new Anthropic({ apiKey });
}

function parseJson<T>(text: string): T {
  const cleaned = text.trim().replace(/^```(?:json)?\n?/, "").replace(/\n?```$/, "");
  return JSON.parse(cleaned) as T;
}

export async function extractThemeBriefWithClaude(sourceMeta: SourceMeta): Promise<ThemeBrief> {
  const client = getClient();
  const message = await client.messages.create({
    model: MODEL,
    max_tokens: 500,
    system:
      "You analyze a YouTube video's public title/description/tags and extract only its general " +
      "theme, format, and narrative structure — never quote or closely paraphrase the source text. " +
      "Respond with JSON only, matching this shape: " +
      '{"topic": string, "format": string, "beats": string[], "tone": string}. ' +
      "topic and format should be short, generic descriptions of the content category " +
      "(e.g. 'a home workout routine', 'hook -> demonstration -> CTA'), not copies of the title.",
    messages: [
      {
        role: "user",
        content: `Title: ${sourceMeta.title}\nDescription: ${sourceMeta.description ?? "(none)"}\nTags: ${(sourceMeta.tags ?? []).join(", ") || "(none)"}`,
      },
    ],
  });

  const text = message.content[0]?.type === "text" ? message.content[0].text : "";
  return parseJson<ThemeBrief>(text);
}

export async function generateScriptWithClaude(brief: ThemeBrief): Promise<ScriptResult> {
  const client = getClient();
  const message = await client.messages.create({
    model: MODEL,
    max_tokens: 400,
    system:
      "You write a completely original 30-55 second vertical video voiceover script for a " +
      "YouTube Short, based only on a theme brief. Never reference or reuse any specific source " +
      "video's wording. Write punchy, spoken narration with a strong hook in the first line. " +
      "Respond with JSON only: {\"script\": string, \"durationSeconds\": number}.",
    messages: [
      {
        role: "user",
        content: `Topic: ${brief.topic}\nFormat: ${brief.format}\nTone: ${brief.tone}\nBeats:\n${brief.beats.map((b) => `- ${b}`).join("\n")}`,
      },
    ],
  });

  const text = message.content[0]?.type === "text" ? message.content[0].text : "";
  return parseJson<ScriptResult>(text);
}

export async function generateMetadataWithClaude(
  brief: ThemeBrief,
  script: string
): Promise<MetadataResult> {
  const client = getClient();
  const message = await client.messages.create({
    model: MODEL,
    max_tokens: 400,
    system:
      "You write a YouTube title, description, and tags for a Short, optimized for the video's " +
      "niche. Respond with JSON only: " +
      '{"title": string, "description": string, "tags": string[]}. Keep title under 100 characters.',
    messages: [
      {
        role: "user",
        content: `Topic: ${brief.topic}\nTone: ${brief.tone}\nScript:\n${script}`,
      },
    ],
  });

  const text = message.content[0]?.type === "text" ? message.content[0].text : "";
  return parseJson<MetadataResult>(text);
}
