// Image-to-Video tools — 5 models
import { z } from "zod";
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import { submitAndPoll } from "../poller.js";
import { TOOL_ENDPOINTS } from "../types.js";
import { resolveImageInput } from "../upload.js";

export function registerImageToVideoTools(server: McpServer): void {
  // ─── LTX-2 Fast I2V ───
  server.tool(
    "ltx2_fast_i2v",
    "Generate video from image+text using LTX-2 Fast (20 credits). Quick image-to-video with optional audio.",
    {
      image: z.string().describe("Image URL or local file path (first frame)"),
      prompt: z.string().describe("Text prompt describing the desired video motion/action"),
      duration: z.number().int().min(3).max(15).default(5).describe("Video duration in seconds"),
      generate_audio: z.boolean().default(false).describe("Generate audio track"),
    },
    async ({ image, prompt, duration, generate_audio }) => {
      const imageUrl = await resolveImageInput(image);
      const ep = TOOL_ENDPOINTS.ltx2_fast_i2v;
      const result = await submitAndPoll(ep.endpoint, ep.scenario, {
        prompt: prompt.trim(),
        image: imageUrl,
        duration,
        generate_audio,
      });
      return { content: [{ type: "text", text: `✅ Video generated: ${result.output}\nTask ID: ${result.taskId}` }] };
    },
  );

  // ─── Veo 3.1 I2V ───
  server.tool(
    "veo_31_i2v",
    "Generate video from image+text using Google Veo 3.1 (200 credits). High-quality image-to-video.",
    {
      image: z.string().describe("Image URL or local file path (first frame)"),
      prompt: z.string().describe("Text prompt describing motion/action"),
      last_image: z.string().default("").describe("Optional last frame image URL/path for guided animation"),
      aspect_ratio: z.enum(["16:9", "9:16", "1:1"]).default("16:9"),
      resolution: z.enum(["720p", "1080p"]).default("720p"),
      duration: z.number().int().min(3).max(30).default(8),
      generate_audio: z.boolean().default(true),
      negative_prompt: z.string().default(""),
      seed: z.string().default("").describe("Seed for reproducibility"),
    },
    async ({ image, prompt, last_image, aspect_ratio, resolution, duration, generate_audio, negative_prompt, seed }) => {
      const imageUrl = await resolveImageInput(image);
      const body: Record<string, unknown> = {
        prompt: prompt.trim(),
        image: imageUrl,
        aspect_ratio,
        resolution,
        duration,
        generate_audio,
      };
      if (last_image) {
        body.last_image = last_image.startsWith("http") ? last_image : await resolveImageInput(last_image);
      }
      if (negative_prompt) body.negative_prompt = negative_prompt.trim();
      if (seed) body.seed = seed;

      const ep = TOOL_ENDPOINTS.veo_31_i2v;
      const result = await submitAndPoll(ep.endpoint, ep.scenario, body);
      return { content: [{ type: "text", text: `✅ Video generated: ${result.output}\nTask ID: ${result.taskId}` }] };
    },
  );

  // ─── Seedance 1.5 Pro I2V ───
  server.tool(
    "seedance_15_pro_i2v",
    "Generate video from image+text using Seedance 1.5 Pro (100 credits). ByteDance I2V.",
    {
      image: z.string().describe("Image URL or local file path"),
      prompt: z.string().describe("Text prompt"),
      aspect_ratio: z.enum(["16:9", "9:16", "1:1"]).default("16:9"),
      resolution: z.enum(["720p", "1080p"]).default("720p"),
      duration: z.number().int().min(3).max(15).default(5),
      generate_audio: z.boolean().default(false),
      camera_fixed: z.boolean().default(false),
      seed: z.number().int().default(-1),
    },
    async ({ image, prompt, aspect_ratio, resolution, duration, generate_audio, camera_fixed, seed }) => {
      const imageUrl = await resolveImageInput(image);
      const ep = TOOL_ENDPOINTS.seedance_15_pro_i2v;
      const result = await submitAndPoll(ep.endpoint, ep.scenario, {
        prompt: prompt.trim(),
        image: imageUrl,
        aspect_ratio,
        resolution,
        duration,
        generate_audio,
        camera_fixed,
        seed: seed === -1 ? -1 : seed,
      });
      return { content: [{ type: "text", text: `✅ Video generated: ${result.output}\nTask ID: ${result.taskId}` }] };
    },
  );

  // ─── PixVerse v5.6 I2V ───
  server.tool(
    "pixverse_56_i2v",
    "Generate video from image+text using PixVerse v5.6 (100 credits). Creative I2V with thinking mode.",
    {
      image: z.string().describe("Image URL or local file path"),
      prompt: z.string().describe("Text prompt"),
      negative_prompt: z.string().default(""),
      duration: z.number().int().min(3).max(15).default(10),
      generate_audio: z.boolean().default(false),
      resolution: z.enum(["720p", "1080p"]).default("720p"),
      resolution_ratio: z.enum(["16:9", "9:16", "1:1"]).default("16:9"),
      thinking_type: z.string().default(""),
      seed: z.number().int().default(-1),
    },
    async ({ image, prompt, negative_prompt, duration, generate_audio, resolution, resolution_ratio, thinking_type, seed }) => {
      const imageUrl = await resolveImageInput(image);
      const body: Record<string, unknown> = {
        prompt: prompt.trim(),
        image: imageUrl,
        duration,
        generate_audio_switch: generate_audio,
        resolution,
        resolution_ratio,
        seed,
      };
      if (negative_prompt) body.negative_prompt = negative_prompt.trim();
      if (thinking_type) body.thinking_type = thinking_type;

      const ep = TOOL_ENDPOINTS.pixverse_56_i2v;
      const result = await submitAndPoll(ep.endpoint, ep.scenario, body);
      return { content: [{ type: "text", text: `✅ Video generated: ${result.output}\nTask ID: ${result.taskId}` }] };
    },
  );

  // ─── Vidu Q3 I2V ───
  server.tool(
    "vidu_q3_i2v",
    "Generate video from image+text using Vidu Q3 (100 credits). I2V with motion amplitude & BGM controls.",
    {
      image: z.string().describe("Image URL or local file path"),
      prompt: z.string().describe("Text prompt"),
      resolution: z.enum(["720p", "1080p"]).default("720p"),
      duration: z.number().int().min(3).max(15).default(5),
      movement_amplitude: z.enum(["auto", "small", "medium", "large"]).default("auto").describe("How much motion"),
      generate_audio: z.boolean().default(false),
      bgm: z.string().default("").describe("Background music URL (optional)"),
      seed: z.string().default(""),
    },
    async ({ image, prompt, resolution, duration, movement_amplitude, generate_audio, bgm, seed }) => {
      const imageUrl = await resolveImageInput(image);
      const body: Record<string, unknown> = {
        prompt: prompt.trim(),
        image: imageUrl,
        resolution,
        duration,
        movement_amplitude,
        generate_audio,
      };
      if (bgm) body.bgm = bgm;
      if (seed) body.seed = seed;

      const ep = TOOL_ENDPOINTS.vidu_q3_i2v;
      const result = await submitAndPoll(ep.endpoint, ep.scenario, body);
      return { content: [{ type: "text", text: `✅ Video generated: ${result.output}\nTask ID: ${result.taskId}` }] };
    },
  );
}
