import { KlingMotionSchema, type KlingMotionInput, type PromptVariation } from "@/lib/schemas/universal-prompt.schema";
import { BasePromptAdapter, extractVariations, type AdapterValidationResult } from "./base.adapter";

export class KlingMotionPromptAdapter extends BasePromptAdapter<KlingMotionInput> {
  platform = "kling_motion" as const;

  validateInput(input: unknown): AdapterValidationResult {
    const result = KlingMotionSchema.safeParse(input);
    if (result.success) return { success: true };
    return {
      success: false,
      errors: result.error.errors.map((e) => `${e.path.join(".")}: ${e.message}`),
    };
  }

  constructSystemPrompt(input: KlingMotionInput, variationCount: number): string {
    // Fix #5: Sertakan language instruction
    // Fix #7: Tambah shotList schema detail agar output konsisten
    const langInstruction =
      input.language === "id"
        ? "Write all textPrompt and script fields in Bahasa Indonesia."
        : "Write all textPrompt and script fields in English.";

    return `You are a Kling AI motion control expert. Generate ${variationCount} precise motion control prompt(s) for Kling AI video generation.

Kling specializes in controlled subject and camera motion. Focus on:
- Precise motion descriptions with timing cues
- Camera path and trajectory with keyframes
- Subject movement and body mechanics
- Background motion/parallax depth
- Smooth transition effects

Rules:
1. Each prompt must describe motion with temporal precision
2. Use professional cinematography and motion control terminology
3. Output MUST be valid JSON matching the schema exactly
4. Generate exactly ${variationCount} variation(s)
5. Each variation should explore a different motion approach for the same subject
6. ${langInstruction}

Output format (strict JSON):
{
  "variations": [
    {
      "index": 0,
      "textPrompt": "detailed motion control prompt",
      "negativePrompt": "undesired motions and artifacts to avoid",
      "jsonOutput": {
        "subject": "...",
        "motionType": "...",
        "cameraPath": "...",
        "subjectMotion": "...",
        "backgroundMotion": "...",
        "transitionType": "...",
        "motionIntensity": "...",
        "timing": "...",
        "style": "..."
      },
      "shotList": [
        {
          "shotNumber": 1,
          "shotType": "wide | medium | close-up | extreme close-up | etc.",
          "cameraAngle": "eye level | high angle | low angle | dutch angle | etc.",
          "cameraMovement": "static | pan left | pan right | tilt up | tilt down | dolly in | dolly out | orbit | crane up | etc.",
          "subject": "subject and its starting position",
          "action": "exact motion: what moves, how it moves, timing (e.g. 'walks left to right, 0s-3s, moderate pace')",
          "duration": "3s",
          "notes": "motion intensity, easing, keyframe notes"
        }
      ],
      "script": "Full motion direction: scene setup, motion sequence, timing breakdown, and director notes"
    }
  ]
}`;
  }

  // Fix #2: variationIndex dihapus — tidak dipakai, satu call menghasilkan semua variasi
  // Fix #5: Language ditampilkan eksplisit di user prompt
  constructUserPrompt(input: KlingMotionInput): string {
    return `Generate ${input.variations} Kling Motion Control prompt(s):

Subject: ${input.subject}
${input.motionType ? `Motion Type: ${input.motionType.replace(/_/g, " ")}` : ""}
${input.cameraPath ? `Camera Path: ${input.cameraPath.replace(/_/g, " ")}` : ""}
${input.subjectMotion ? `Subject Motion: ${input.subjectMotion.replace(/_/g, " ")}` : ""}
${input.backgroundMotion ? `Background Motion: ${input.backgroundMotion}` : ""}
${input.transitionType ? `Transition: ${input.transitionType}` : ""}
${input.motionIntensity ? `Intensity: ${input.motionIntensity}` : ""}
${input.style ? `Visual Style: ${input.style}` : ""}
${input.mood ? `Mood: ${input.mood}` : ""}
${input.negativePrompt ? `Avoid: ${input.negativePrompt}` : ""}
Mode: ${input.mode}
Language: ${input.language === "id" ? "Bahasa Indonesia" : "English"}

${input.mode === "advanced" ? "Include detailed timing notes, keyframe breakdown, and multi-angle shot list." : "Keep motion descriptions clear and achievable."}`;
  }

  transformOutput(rawOutput: string, input: KlingMotionInput): PromptVariation {
    const parsed = this.parseJsonSafe(rawOutput);
    const variations = parsed ? extractVariations(parsed) : null;
    if (variations && variations.length > 0) {
      return variations[0];
    }
    return {
      index: 0,
      textPrompt: rawOutput,
      negativePrompt: this.buildNegativePrompt(input),
      jsonOutput: this.generateJsonOutput(input),
    };
  }

  generateTextPrompt(input: KlingMotionInput): string {
    return [
      input.subject,
      input.motionType && `${input.motionType.replace(/_/g, " ")} motion`,
      input.cameraPath && `${input.cameraPath.replace(/_/g, " ")} camera path`,
      input.subjectMotion && `subject ${input.subjectMotion.replace(/_/g, " ")}`,
      input.backgroundMotion && `${input.backgroundMotion} background`,
      input.style,
      input.mood,
      `smooth motion control`,
    ]
      .filter(Boolean)
      .join(", ");
  }

  generateJsonOutput(input: KlingMotionInput): Record<string, unknown> {
    return {
      platform: "kling_motion",
      subject: input.subject,
      motionType: input.motionType ?? "smooth",
      cameraPath: input.cameraPath ?? "linear",
      subjectMotion: input.subjectMotion ?? "static",
      backgroundMotion: input.backgroundMotion ?? "static",
      transitionType: input.transitionType ?? "none",
      motionIntensity: input.motionIntensity ?? "moderate",
      style: input.style ?? "cinematic",
      negativePrompt: this.buildNegativePrompt(input),
    };
  }

  protected override getDefaultNegativePrompts(): string[] {
    return [
      "jerky motion",
      "unnatural movement",
      "motion blur artifacts",
      "temporal inconsistency",
      "flickering",
      "abrupt cuts",
      "unstable footage",
    ];
  }
}
