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

export class HiggsfieldPromptAdapter extends BasePromptAdapter<HiggsfieldInput> {
  platform = "higgsfield" as const;

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

  constructSystemPrompt(input: HiggsfieldInput, 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 Higgsfield AI specialist focusing on physics-based cinematic video generation. Create ${variationCount} prompt(s) that leverage Higgsfield's physics simulation capabilities.

Higgsfield excels at:
- Realistic physics simulations (fluid, cloth, particle, rigid body)
- Cinematic blockbuster aesthetics with photorealistic rendering
- Complex environmental effects and atmospheric conditions
- Dynamic interactions between physics systems

Rules:
1. Each prompt must describe physical interactions with scientific accuracy
2. Specify physics parameters: mass, velocity, turbulence, viscosity where relevant
3. Output MUST be valid JSON matching the schema exactly
4. Generate exactly ${variationCount} variation(s)
5. Each variation should explore a different physics scenario or environmental condition
6. Negative prompts must specifically target physics rendering artifacts
7. ${langInstruction}

Output format (strict JSON):
{
  "variations": [
    {
      "index": 0,
      "textPrompt": "detailed physics-aware prompt with environment and simulation specs",
      "negativePrompt": "specific physics artifacts and rendering errors to avoid",
      "jsonOutput": {
        "subject": "...",
        "physicsType": "...",
        "particleEffect": "...",
        "fluidDynamics": "...",
        "environmentType": "...",
        "cinematicStyle": "...",
        "colorPalette": "...",
        "lightingSetup": "...",
        "renderQuality": "..."
      },
      "shotList": [
        {
          "shotNumber": 1,
          "shotType": "wide | medium | close-up | extreme close-up | macro | overhead | etc.",
          "cameraAngle": "eye level | high angle | low angle | bird's eye | worm's eye | etc.",
          "cameraMovement": "static | slow push in | pull back | crane up | orbit | handheld | etc.",
          "subject": "subject and physics elements in frame",
          "action": "physics event description (e.g. 'fluid splashes against surface, particles disperse outward')",
          "duration": "3s",
          "notes": "physics simulation focus, render quality priority, lighting conditions"
        }
      ],
      "script": "Full scene direction: physics event sequence, environmental setup, lighting motivation, and cinematic direction notes"
    }
  ]
}`;
  }

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

Subject: ${input.subject}
${input.physicsType ? `Physics Simulation: ${input.physicsType}` : ""}
${input.particleEffect ? `Particle Effect: ${input.particleEffect.replace(/_/g, " ")}` : ""}
${input.fluidDynamics ? `Fluid Dynamics: ${input.fluidDynamics}` : ""}
${input.environmentType ? `Environment: ${input.environmentType}` : ""}
${input.cinematicStyle ? `Cinematic Style: ${input.cinematicStyle.replace(/_/g, " ")}` : ""}
${input.colorPalette ? `Color Palette: ${input.colorPalette}` : ""}
${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 physics parameters, particle/fluid interaction notes, lighting setup, and multi-shot breakdown." : "Focus on the main physics interaction and cinematic impact."}`;
  }

  transformOutput(rawOutput: string, input: HiggsfieldInput): 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: HiggsfieldInput): string {
    return [
      input.subject,
      input.physicsType && `${input.physicsType} physics simulation`,
      input.particleEffect &&
        input.particleEffect !== "none" &&
        `${input.particleEffect.replace(/_/g, " ")} particles`,
      input.fluidDynamics &&
        input.fluidDynamics !== "none" &&
        `${input.fluidDynamics} fluid`,
      input.environmentType,
      input.cinematicStyle && `${input.cinematicStyle.replace(/_/g, " ")} style`,
      input.style,
      input.mood,
      "photorealistic render",
      "high detail",
    ]
      .filter(Boolean)
      .join(", ");
  }

  generateJsonOutput(input: HiggsfieldInput): Record<string, unknown> {
    return {
      platform: "higgsfield",
      subject: input.subject,
      physicsType: input.physicsType ?? "gravity",
      particleEffect: input.particleEffect ?? "none",
      fluidDynamics: input.fluidDynamics ?? "none",
      environmentType: input.environmentType ?? "outdoor",
      cinematicStyle: input.cinematicStyle ?? "blockbuster",
      colorPalette: input.colorPalette ?? "cinematic",
      style: input.style ?? "photorealistic",
      negativePrompt: this.buildNegativePrompt(input),
    };
  }

  protected override getDefaultNegativePrompts(): string[] {
    return [
      "unrealistic physics",
      "clipping geometry",
      "z-fighting artifacts",
      "low poly",
      "cartoon style",
      "flat lighting",
      "no depth",
      "oversmoothed surfaces",
    ];
  }
}
