"use client";

import { useState, useRef, useEffect } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  Wand2, X,
  Image as ImageIcon, Loader2
} from "lucide-react";
import { toast } from "sonner";
import type { Platform } from "@/types";
import { cn } from "@/lib/utils";

// Platform-specific field configs
const PLATFORM_FIELDS: Record<string, Array<{
  key: string; label: string; type: "select" | "textarea" | "text";
  options?: { value: string; label: string }[];
  placeholder?: string; advanced?: boolean;
}>> = {
  seedance: [
    { key: "cameraMotion", label: "Camera Motion", type: "select", options: [
      { value: "static",     label: "Static"      },
      { value: "pan_left",   label: "Pan Left"    },
      { value: "pan_right",  label: "Pan Right"   },
      { value: "tilt_up",    label: "Tilt Up"     },
      { value: "tilt_down",  label: "Tilt Down"   },
      { value: "zoom_in",    label: "Zoom In"     },
      { value: "zoom_out",   label: "Zoom Out"    },
      { value: "dolly_in",   label: "Dolly In"    },
      { value: "dolly_out",  label: "Dolly Out"   },
      { value: "orbit",      label: "Orbit"       },
      { value: "handheld",   label: "Handheld"    },
      { value: "crane_up",   label: "Crane Up"    },
      { value: "crane_down", label: "Crane Down"  },
    ]},
    { key: "cameraAngle", label: "Camera Angle", type: "select", options: [
      { value: "eye_level", label: "Eye Level" }, { value: "low_angle", label: "Low Angle" },
      { value: "high_angle", label: "High Angle" }, { value: "bird_eye", label: "Bird Eye" },
      { value: "dutch_angle", label: "Dutch Angle" },
    ]},
    { key: "lighting", label: "Lighting", type: "select", options: [
      { value: "natural", label: "Natural" }, { value: "golden_hour", label: "Golden Hour" },
      { value: "blue_hour", label: "Blue Hour" }, { value: "studio", label: "Studio" },
      { value: "dramatic", label: "Dramatic" }, { value: "neon", label: "Neon" },
    ]},
    { key: "colorGrading", label: "Color Grading", type: "select", options: [
      { value: "cinematic", label: "Cinematic" }, { value: "vintage", label: "Vintage" },
      { value: "vibrant", label: "Vibrant" }, { value: "noir", label: "Noir" },
      { value: "teal_orange", label: "Teal & Orange" },
    ]},
    { key: "duration", label: "Duration", type: "select", options: [
      { value: "3s", label: "3 Detik" }, { value: "5s", label: "5 Detik" },
      { value: "8s", label: "8 Detik" }, { value: "10s", label: "10 Detik" },
    ]},
    { key: "resolution", label: "Resolution", type: "select", advanced: true, options: [
      { value: "720p", label: "720p" }, { value: "1080p", label: "1080p" }, { value: "4K", label: "4K" },
    ]},
    { key: "fps", label: "FPS", type: "select", advanced: true, options: [
      { value: "24", label: "24fps (Cinematic)" }, { value: "30", label: "30fps" }, { value: "60", label: "60fps" },
    ]},
    { key: "sceneDescription", label: "Deskripsi Adegan", type: "textarea", advanced: true, placeholder: "Detail tambahan tentang adegan, environment, dan suasana..." },
  ],
  gemini_omni: [
    { key: "outputType", label: "Output Type", type: "select", options: [
      { value: "image", label: "Image" }, { value: "video", label: "Video" }, { value: "audio", label: "Audio" },
    ]},
    { key: "quality", label: "Quality", type: "select", options: [
      { value: "standard", label: "Standard" }, { value: "high", label: "High" }, { value: "ultra", label: "Ultra" },
    ]},
    { key: "aspectRatio", label: "Aspect Ratio", type: "select", options: [
      { value: "1:1", label: "1:1 (Square)" }, { value: "16:9", label: "16:9 (Landscape)" },
      { value: "9:16", label: "9:16 (Portrait)" }, { value: "4:3", label: "4:3" },
    ]},
    // Fix #2: safetyLevel ditambahkan — sebelumnya ada di schema tapi tidak bisa diisi dari UI
    { key: "safetyLevel", label: "Safety Level", type: "select", advanced: true, options: [
      { value: "default", label: "Default" }, { value: "strict", label: "Strict" },
    ]},
    { key: "additionalContext", label: "Konteks Tambahan", type: "textarea", advanced: true, placeholder: "Informasi tambahan untuk meningkatkan kualitas prompt..." },
  ],
  kling_motion: [
    { key: "motionType", label: "Motion Type", type: "select", options: [
      { value: "smooth", label: "Smooth" }, { value: "dynamic", label: "Dynamic" },
      { value: "slow_motion", label: "Slow Motion" }, { value: "time_lapse", label: "Time Lapse" },
    ]},
    { key: "cameraPath", label: "Camera Path", type: "select", options: [
      { value: "linear", label: "Linear" }, { value: "curved", label: "Curved" },
      { value: "circular", label: "Circular" }, { value: "spiral", label: "Spiral" },
    ]},
    { key: "subjectMotion", label: "Subject Motion", type: "select", options: [
      { value: "static", label: "Static" }, { value: "walking", label: "Walking" },
      { value: "running", label: "Running" }, { value: "dancing", label: "Dancing" }, { value: "floating", label: "Floating" },
    ]},
    { key: "backgroundMotion", label: "Background Motion", type: "select", advanced: true, options: [
      { value: "static", label: "Static" }, { value: "parallax", label: "Parallax" }, { value: "blur", label: "Blur" },
    ]},
    // Fix 7: motionIntensity added to match TypeScript type
    { key: "motionIntensity", label: "Motion Intensity", type: "select", advanced: true, options: [
      { value: "subtle", label: "Subtle" }, { value: "moderate", label: "Moderate" }, { value: "intense", label: "Intense" },
    ]},
    // Fix #3: transitionType ditambahkan — ada di schema tapi tidak bisa diisi dari UI
    { key: "transitionType", label: "Transition Type", type: "select", advanced: true, options: [
      { value: "none", label: "None" }, { value: "cut", label: "Cut" }, { value: "fade", label: "Fade" },
      { value: "dissolve", label: "Dissolve" }, { value: "wipe", label: "Wipe" }, { value: "morph", label: "Morph" },
    ]},
  ],
  higgsfield: [
    { key: "physicsType", label: "Physics Type", type: "select", options: [
      { value: "gravity", label: "Gravity" }, { value: "fluid", label: "Fluid" },
      { value: "cloth", label: "Cloth" }, { value: "fire", label: "Fire" }, { value: "explosion", label: "Explosion" },
    ]},
    { key: "particleEffect", label: "Particle Effect", type: "select", options: [
      { value: "none", label: "None" }, { value: "sparkles", label: "Sparkles" },
      { value: "dust", label: "Dust" }, { value: "rain", label: "Rain" }, { value: "snow", label: "Snow" },
      { value: "embers", label: "Embers" },
    ]},
    { key: "environmentType", label: "Environment", type: "select", options: [
      { value: "outdoor", label: "Outdoor" }, { value: "indoor", label: "Indoor" },
      { value: "underwater", label: "Underwater" }, { value: "space", label: "Space" }, { value: "abstract", label: "Abstract" },
    ]},
    // Fix #4: fluidDynamics ditambahkan — ada di schema tapi tidak bisa diisi dari UI
    { key: "fluidDynamics", label: "Fluid Dynamics", type: "select", options: [
      { value: "none", label: "None" }, { value: "water", label: "Water" }, { value: "lava", label: "Lava" },
      { value: "oil", label: "Oil" }, { value: "plasma", label: "Plasma" }, { value: "mist", label: "Mist" },
    ]},
    { key: "cinematicStyle", label: "Cinematic Style", type: "select", advanced: true, options: [
      { value: "blockbuster", label: "Blockbuster" }, { value: "indie", label: "Indie" },
      { value: "music_video", label: "Music Video" }, { value: "commercial", label: "Commercial" },
    ]},
    // Fix 7: colorPalette added to match TypeScript type
    { key: "colorPalette", label: "Color Palette", type: "text", advanced: true, placeholder: "misal: warm sunset tones, cool neon blues..." },
  ],
  tiktok_ugc: [
    { key: "productName", label: "Nama Produk", type: "text", placeholder: "Nama produk yang dipromosikan" },
    { key: "targetAudience", label: "Target Audience", type: "text", placeholder: "misal: wanita 18-25 tahun yang suka skincare" },
    { key: "hookType", label: "Hook Style", type: "select", options: [
      { value: "question", label: "Question Hook" }, { value: "shock", label: "Shock Value" },
      { value: "story", label: "Story Hook" }, { value: "benefit", label: "Benefit Hook" },
      { value: "curiosity", label: "Curiosity Gap" },
    ]},
    { key: "ugcPersona", label: "UGC Persona", type: "select", options: [
      { value: "everyday_user", label: "Everyday User" }, { value: "expert", label: "Expert" },
      { value: "mom", label: "Mom" }, { value: "student", label: "Student" }, { value: "skeptic_converted", label: "Skeptic Converted" },
    ]},
    { key: "videoDuration", label: "Durasi Video", type: "select", options: [
      { value: "15s", label: "15 Detik" }, { value: "30s", label: "30 Detik" }, { value: "60s", label: "60 Detik" },
    ]},
    { key: "painPoint", label: "Pain Point", type: "text", advanced: true, placeholder: "Masalah yang dialami target audience" },
    { key: "benefit", label: "Benefit Utama", type: "text", advanced: true, placeholder: "Manfaat terbesar produk ini" },
    { key: "ctaType", label: "CTA", type: "select", advanced: true, options: [
      { value: "link_in_bio", label: "Link in Bio" }, { value: "comment", label: "Comment" },
      { value: "share", label: "Share" }, { value: "purchase", label: "Purchase" },
    ]},
    { key: "trendReference", label: "Trend Reference", type: "text", advanced: true, placeholder: "misal: #BookTok, POV trend, duet challenge..." },
  ],
};

const SUBJECT_MAX = 500;

// Fix 11: Zod schema for React Hook Form validation
const formSchema = z.object({
  subject: z.string().min(3, "Subjek minimal 3 karakter").max(SUBJECT_MAX, `Subjek maksimal ${SUBJECT_MAX} karakter`),
  style: z.string().optional(),
  mood: z.string().optional(),
});

type FormValues = z.infer<typeof formSchema>;

interface GeneratorFormProps {
  platform: Platform;
  onGenerate: (data: Record<string, unknown>) => Promise<void>;
  loading: boolean;
}

export default function GeneratorForm({ platform, onGenerate, loading }: GeneratorFormProps) {
  // Fix 11: Replaced 6 useState with useForm + Zod validation
  const {
    register,
    handleSubmit,
    setValue,
    watch,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(formSchema),
    defaultValues: { subject: "", style: "", mood: "" },
  });

  const subject = watch("subject");

  // Keep these as state — they have special handling (file upload, toggle UI)
  const [mode, setMode] = useState<"simple" | "advanced">("simple");
  const [language, setLanguage] = useState<"id" | "en">("id");
  const [variations, setVariations] = useState<1 | 3 | 5>(1);
  const [negativePrompt, setNegativePrompt] = useState("");
  const [fieldValues, setFieldValues] = useState<Record<string, string>>({});
  const [referenceImage, setReferenceImage] = useState<string | null>(null);
  const [uploadingImage, setUploadingImage] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Load prefill data from sessionStorage (template atau storyboard scene pipeline)
  useEffect(() => {
    // Cek dua key: "template_input" (dari Templates page) dan
    // "scene_prefill" (dari SceneToGeneratorButton — storyboard pipeline)
    const raw =
      sessionStorage.getItem("template_input") ??
      sessionStorage.getItem("scene_prefill");

    if (!raw) return;

    // Hapus kedua key sekaligus untuk kebersihan
    sessionStorage.removeItem("template_input");
    sessionStorage.removeItem("scene_prefill");

    try {
      const data = JSON.parse(raw) as Record<string, unknown>;

      if (typeof data.subject === "string") setValue("subject", data.subject);
      if (typeof data.style === "string")   setValue("style",   data.style);
      if (typeof data.mood === "string")    setValue("mood",    data.mood);
      if (typeof data.negativePrompt === "string") setNegativePrompt(data.negativePrompt);
      if (data.mode === "advanced") setMode("advanced");
      if (data.language === "en")  setLanguage("en");
      if (data.variations === 3 || data.variations === 5) setVariations(data.variations as 3 | 5);
      if (typeof data.referenceImageUrl === "string") setReferenceImage(data.referenceImageUrl);

      // Platform-specific fields
      const platformFields = PLATFORM_FIELDS[platform] ?? [];
      const newFieldValues: Record<string, string> = {};
      for (const field of platformFields) {
        const val = data[field.key];
        if (typeof val === "string" && val) {
          newFieldValues[field.key] = val;
        }
      }
      if (Object.keys(newFieldValues).length > 0) {
        setFieldValues(newFieldValues);
      }

      // Beri tahu user dari mana data ini berasal
      const isFromScene = data._source === "storyboard_scene";
      toast.success(
        isFromScene
          ? `Scene ${data._sceneNumber ?? ""} dimuat ke form! 🎬`
          : "Template dimuat ke form!"
      );
    } catch {
      // ignore parse errors
    }
  // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [platform]);

  const platformFields = PLATFORM_FIELDS[platform] ?? [];
  const visibleFields = platformFields.filter((f) => mode === "advanced" || !f.advanced);

  function setField(key: string, value: string) {
    setFieldValues((prev) => ({ ...prev, [key]: value }));
  }

  async function handleImageUpload(e: React.ChangeEvent<HTMLInputElement>) {
    const file = e.target.files?.[0];
    if (!file) return;

    setUploadingImage(true);
    try {
      const formData = new FormData();
      formData.append("file", file);
      const res = await fetch("/api/upload", { method: "POST", body: formData });
      const data = await res.json();
      if (data.url) {
        setReferenceImage(data.url);
        toast.success("Gambar referensi berhasil diupload");
      } else {
        toast.error(data.error ?? "Gagal upload gambar");
      }
    } catch {
      toast.error("Gagal upload gambar");
    } finally {
      setUploadingImage(false);
    }
  }

  // Fix 11: onSubmit now uses RHF handleSubmit — validation is automatic
  // BUG-08 FIX: Tambahkan field `platform` agar Zod discriminated union di API bisa validasi.
  // Tanpa `platform`, GenerateRequestSchema.safeParse selalu gagal → setiap generate = 400 error.
  const onSubmit = async (values: FormValues) => {
    await onGenerate({
      platform,          // ← BUG-08 FIX: wajib ada agar input lolos validasi discriminated union
      mode,
      language,
      variations,
      subject: values.subject,
      style: values.style || undefined,
      mood: values.mood || undefined,
      negativePrompt: negativePrompt || undefined,
      referenceImageUrl: referenceImage || undefined,
      ...Object.fromEntries(
        Object.entries(fieldValues).filter(([, v]) => v !== "")
      ),
    });
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
      {/* Mode toggle */}
      <div className="glass-card rounded-xl p-1 flex gap-1">
        {(["simple", "advanced"] as const).map((m) => (
          <button
            key={m}
            type="button"
            onClick={() => setMode(m)}
            className={cn(
              "flex-1 py-2 px-3 rounded-lg text-sm font-medium transition-colors capitalize",
              mode === m
                ? "bg-primary text-primary-foreground"
                : "text-muted-foreground hover:text-foreground"
            )}
          >
            {m === "simple" ? "Simple Mode" : "Advanced Mode"}
          </button>
        ))}
      </div>

      {/* Subject */}
      <div className="glass-card rounded-xl p-4 space-y-3">
        <div>
          <div className="flex items-center justify-between mb-1.5">
            <label className="text-sm font-medium">
              Subjek / Topik <span className="text-red-400">*</span>
            </label>
            <span className={cn(
              "text-xs tabular-nums",
              subject.length > SUBJECT_MAX * 0.9 ? "text-red-400" : "text-muted-foreground"
            )}>
              {subject.length}/{SUBJECT_MAX}
            </span>
          </div>
          <textarea
            {...register("subject")}
            placeholder={platform === "tiktok_ugc"
              ? "Produk atau topik yang ingin dipromosikan..."
              : "Deskripsikan subjek utama video yang ingin kamu buat..."}
            rows={3}
            className={cn(
              "w-full px-3 py-2.5 rounded-lg bg-accent border focus:outline-none focus:ring-1 transition-colors text-sm resize-none",
              errors.subject
                ? "border-red-400 focus:border-red-400 focus:ring-red-400"
                : "border-border focus:border-primary focus:ring-primary"
            )}
          />
          {errors.subject && (
            <p className="text-xs text-red-400 mt-1">{errors.subject.message}</p>
          )}
        </div>

        <div className="grid grid-cols-2 gap-3">
          <div>
            <label className="text-xs text-muted-foreground mb-1 block">Style</label>
            <input
              {...register("style")}
              placeholder="misal: cinematic, anime..."
              className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm"
            />
          </div>
          <div>
            <label className="text-xs text-muted-foreground mb-1 block">Mood</label>
            <input
              {...register("mood")}
              placeholder="misal: dramatic, peaceful..."
              className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm"
            />
          </div>
        </div>
      </div>

      {/* Platform-specific fields */}
      {visibleFields.length > 0 && (
        <div className="glass-card rounded-xl p-4 space-y-3">
          <h3 className="text-sm font-medium text-muted-foreground">Parameter Platform</h3>
          <div className="grid grid-cols-2 gap-3">
            {visibleFields.map((field) => (
              <div
                key={field.key}
                className={field.type === "textarea" ? "col-span-2" : ""}
              >
                <label className="text-xs text-muted-foreground mb-1 block">
                  {field.label}
                </label>
                {field.type === "select" ? (
                  <select
                    value={fieldValues[field.key] ?? ""}
                    onChange={(e) => setField(field.key, e.target.value)}
                    className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm"
                  >
                    <option value="">Auto</option>
                    {field.options?.map((opt) => (
                      <option key={opt.value} value={opt.value}>{opt.label}</option>
                    ))}
                  </select>
                ) : field.type === "textarea" ? (
                  <textarea
                    value={fieldValues[field.key] ?? ""}
                    onChange={(e) => setField(field.key, e.target.value)}
                    placeholder={field.placeholder}
                    rows={2}
                    className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm resize-none"
                  />
                ) : (
                  <input
                    value={fieldValues[field.key] ?? ""}
                    onChange={(e) => setField(field.key, e.target.value)}
                    placeholder={field.placeholder}
                    className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm"
                  />
                )}
              </div>
            ))}
          </div>
        </div>
      )}

      {/* Advanced options */}
      {mode === "advanced" && (
        <div className="glass-card rounded-xl p-4 space-y-3">
          <h3 className="text-sm font-medium text-muted-foreground">Opsi Lanjutan</h3>

          {/* Negative prompt */}
          <div>
            <label className="text-xs text-muted-foreground mb-1 block">
              Negative Prompt (otomatis bila kosong)
            </label>
            <textarea
              value={negativePrompt}
              onChange={(e) => setNegativePrompt(e.target.value)}
              placeholder="Hal yang ingin dihindari dalam output..."
              rows={2}
              className="w-full px-3 py-2 rounded-lg bg-accent border border-border focus:border-primary focus:outline-none text-sm resize-none"
            />
          </div>

          {/* Reference image */}
          <div>
            <label className="text-xs text-muted-foreground mb-1 block">Gambar Referensi</label>
            {referenceImage ? (
              <div className="relative">
                <img
                  src={referenceImage}
                  alt="Reference"
                  className="w-full h-32 object-cover rounded-lg"
                />
                <button
                  type="button"
                  onClick={() => setReferenceImage(null)}
                  className="absolute top-2 right-2 w-6 h-6 rounded-full bg-background/80 flex items-center justify-center hover:bg-background transition-colors"
                >
                  <X className="w-3.5 h-3.5" />
                </button>
              </div>
            ) : (
              <button
                type="button"
                onClick={() => fileInputRef.current?.click()}
                disabled={uploadingImage}
                className="w-full h-20 rounded-lg border-2 border-dashed border-border hover:border-primary/50 flex flex-col items-center justify-center gap-1.5 text-muted-foreground hover:text-foreground transition-colors text-sm"
              >
                {uploadingImage ? (
                  <><Loader2 className="w-4 h-4 animate-spin" /> Uploading...</>
                ) : (
                  <><ImageIcon className="w-4 h-4" /> Upload gambar referensi</>
                )}
              </button>
            )}
            <input
              ref={fileInputRef}
              type="file"
              accept="image/*"
              className="hidden"
              onChange={handleImageUpload}
            />
          </div>
        </div>
      )}

      {/* Settings bar */}
      <div className="glass-card rounded-xl p-3 flex items-center gap-3 flex-wrap">
        {/* Language */}
        <div className="flex items-center gap-1.5">
          <span className="text-xs text-muted-foreground">Bahasa:</span>
          <div className="flex rounded-lg bg-accent overflow-hidden">
            {(["id", "en"] as const).map((lang) => (
              <button
                key={lang}
                type="button"
                onClick={() => setLanguage(lang)}
                className={cn(
                  "px-2.5 py-1 text-xs font-medium transition-colors",
                  language === lang ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
                )}
              >
                {lang === "id" ? "🇮🇩 ID" : "🇬🇧 EN"}
              </button>
            ))}
          </div>
        </div>

        {/* Variations */}
        <div className="flex items-center gap-1.5">
          <span className="text-xs text-muted-foreground">Variasi:</span>
          <div className="flex rounded-lg bg-accent overflow-hidden">
            {([1, 3, 5] as const).map((v) => (
              <button
                key={v}
                type="button"
                onClick={() => setVariations(v)}
                className={cn(
                  "px-2.5 py-1 text-xs font-medium transition-colors",
                  variations === v ? "bg-primary text-primary-foreground" : "text-muted-foreground hover:text-foreground"
                )}
              >
                {v}x
              </button>
            ))}
          </div>
        </div>
      </div>

      {/* Generate button - sticky */}
      <div className="sticky bottom-0 bg-background/80 backdrop-blur-sm pb-2 -mx-1 px-1">
        <button
          type="submit"
          disabled={loading || !subject.trim()}
          className="w-full py-3.5 rounded-xl bg-gradient-to-r from-purple-600 to-cyan-600 text-white font-semibold hover:opacity-90 transition-all disabled:opacity-50 flex items-center justify-center gap-2 shadow-lg shadow-purple-500/25"
        >
          {loading ? (
            <><Loader2 className="w-4 h-4 animate-spin" /> Generating...</>
          ) : (
            <><Wand2 className="w-4 h-4" /> Generate Prompt</>
          )}
        </button>
      </div>
    </form>
  );
}
