"use client";

import { useRef, useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Textarea } from "@/components/ui/textarea";
import {
  Card,
  CardContent,
  CardDescription,
  CardHeader,
  CardTitle,
} from "@/components/ui/card";
import { ImagePlus, X, Loader2 } from "lucide-react";

export const PLATFORMS = ["instagram", "tiktok", "nextdoor"] as const;
export const GOALS = [
  { value: "app_downloads", label: "App Downloads", description: "Drive installs from App Store and Google Play" },
  { value: "brand_awareness", label: "Brand Awareness", description: "Maximize reach and impressions across platforms" },
  { value: "engagement", label: "Engagement", description: "Boost likes, comments, shares, and saves" },
] as const;

export interface CampaignData {
  id?: string;
  name: string;
  platforms: string[];
  config: {
    goal: string;
    keyMessage: string;
    socialProof?: string;
    targetAudience?: string;
    visualDirection?: string;
    competitorApps?: string;
    variations?: number;
    useTrendReport?: boolean;
    screenshots?: string[];
  };
}

interface CampaignFormProps {
  initialData?: CampaignData;
  mode?: "create" | "edit";
}

export function CampaignForm({ initialData, mode = "create" }: CampaignFormProps) {
  const router = useRouter();
  const [loading, setLoading] = useState(false);
  const [error, setError] = useState("");
  const [selectedPlatforms, setSelectedPlatforms] = useState<string[]>(
    initialData?.platforms || ["instagram"]
  );
  const [selectedGoal, setSelectedGoal] = useState(
    initialData?.config.goal || "app_downloads"
  );
  const [screenshots, setScreenshots] = useState<
    { file?: File; preview: string; uploadedPath?: string }[]
  >(() => {
    // Pre-populate from existing campaign screenshots
    const existing = initialData?.config.screenshots || [];
    return existing.map((p) => ({
      preview: `/api/files/${p}`,
      uploadedPath: p,
    }));
  });
  const [uploading, setUploading] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  function handleFilesSelected(files: FileList | null) {
    if (!files) return;
    const newScreenshots = Array.from(files)
      .filter((f) => f.type.startsWith("image/"))
      .map((file) => ({
        file,
        preview: URL.createObjectURL(file),
      }));
    setScreenshots((prev) => [...prev, ...newScreenshots]);
  }

  function removeScreenshot(index: number) {
    setScreenshots((prev) => {
      const next = [...prev];
      if (next[index].preview.startsWith("blob:")) {
        URL.revokeObjectURL(next[index].preview);
      }
      next.splice(index, 1);
      return next;
    });
  }

  async function uploadScreenshots(): Promise<string[]> {
    if (screenshots.length === 0) return [];

    const needUpload = screenshots.filter((s) => !s.uploadedPath && s.file);
    if (needUpload.length === 0) {
      return screenshots.filter((s) => s.uploadedPath).map((s) => s.uploadedPath!);
    }

    setUploading(true);
    const formData = new FormData();
    for (const s of needUpload) {
      formData.append("files", s.file!);
    }

    const res = await fetch("/api/uploads", {
      method: "POST",
      body: formData,
    });

    if (!res.ok) {
      setUploading(false);
      throw new Error("Failed to upload screenshots");
    }

    const data = await res.json();
    const uploadedPaths: string[] = data.uploaded.map(
      (u: { path: string }) => u.path
    );

    // Map uploaded paths back to screenshots
    let uploadIdx = 0;
    setScreenshots((prev) =>
      prev.map((s) => {
        if (!s.uploadedPath) {
          return { ...s, uploadedPath: uploadedPaths[uploadIdx++] };
        }
        return s;
      })
    );

    setUploading(false);

    // Return all paths (previously uploaded + newly uploaded)
    const allPaths: string[] = [];
    let newIdx = 0;
    for (const s of screenshots) {
      if (s.uploadedPath) {
        allPaths.push(s.uploadedPath);
      } else {
        allPaths.push(uploadedPaths[newIdx++]);
      }
    }
    return allPaths;
  }

  async function handleSubmit(e: React.FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setError("");

    if (selectedPlatforms.length === 0) {
      setError("Select at least one platform.");
      return;
    }

    setLoading(true);

    let screenshotPaths: string[] = [];
    try {
      screenshotPaths = await uploadScreenshots();
    } catch {
      setError("Failed to upload screenshots. Please try again.");
      setLoading(false);
      return;
    }

    const formData = new FormData(e.currentTarget);

    const body = {
      name: formData.get("name") as string,
      platforms: selectedPlatforms,
      config: {
        goal: formData.get("goal") as string,
        keyMessage: formData.get("keyMessage") as string,
        socialProof: formData.get("socialProof") as string,
        targetAudience: formData.get("targetAudience") as string,
        visualDirection: formData.get("visualDirection") as string,
        competitorApps: formData.get("competitorApps") as string,
        variations: Number(formData.get("variations")) || 5,
        useTrendReport: formData.get("useTrendReport") === "on",
        screenshots: screenshotPaths,
      },
    };

    const isEdit = mode === "edit" && initialData?.id;
    const url = isEdit
      ? `/api/campaigns/${initialData.id}`
      : "/api/campaigns";
    const method = isEdit ? "PATCH" : "POST";

    const res = await fetch(url, {
      method,
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(
        isEdit
          ? { name: body.name, platforms: JSON.stringify(body.platforms), config: JSON.stringify(body.config) }
          : body
      ),
    });

    if (res.ok) {
      if (isEdit) {
        router.refresh();
      } else {
        const campaign = await res.json();
        router.push(`/campaigns/${campaign.id}`);
      }
    } else {
      const data = await res.json().catch(() => null);
      setError(data?.error || "Failed to save campaign. Please try again.");
      setLoading(false);
    }
  }

  function togglePlatform(platform: string) {
    setSelectedPlatforms((prev) =>
      prev.includes(platform)
        ? prev.filter((p) => p !== platform)
        : [...prev, platform]
    );
  }

  return (
    <Card>
      <CardHeader>
        <CardTitle>{mode === "edit" ? "Edit Campaign" : "New Campaign"}</CardTitle>
        <CardDescription>
          {mode === "edit"
            ? "Update campaign details before launching"
            : "Configure your campaign and launch the AI pipeline"}
        </CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit} className="space-y-6">
          <div className="space-y-2">
            <Label htmlFor="name">Campaign Name</Label>
            <Input
              id="name"
              name="name"
              placeholder="Spring Launch Campaign"
              defaultValue={initialData?.name || ""}
              required
            />
          </div>

          <div className="space-y-2">
            <Label>Platforms</Label>
            <div className="flex gap-3">
              {PLATFORMS.map((platform) => (
                <button
                  key={platform}
                  type="button"
                  onClick={() => togglePlatform(platform)}
                  className={`rounded-lg border px-4 py-2 text-sm font-medium transition-colors ${
                    selectedPlatforms.includes(platform)
                      ? "border-primary bg-primary text-primary-foreground"
                      : "border-border hover:bg-muted"
                  }`}
                >
                  {platform.charAt(0).toUpperCase() + platform.slice(1)}
                </button>
              ))}
            </div>
          </div>

          <div className="space-y-2">
            <Label>Campaign Goal</Label>
            <input type="hidden" name="goal" value={selectedGoal} />
            <div className="grid gap-2">
              {GOALS.map((goal) => (
                <button
                  key={goal.value}
                  type="button"
                  onClick={() => setSelectedGoal(goal.value)}
                  className={`rounded-lg border px-4 py-3 text-left transition-colors ${
                    selectedGoal === goal.value
                      ? "border-primary bg-primary/5"
                      : "border-border hover:bg-muted"
                  }`}
                >
                  <div className="text-sm font-medium">{goal.label}</div>
                  <div className="text-xs text-muted-foreground">{goal.description}</div>
                </button>
              ))}
            </div>
          </div>

          <div className="space-y-2">
            <Label htmlFor="keyMessage">Key Message</Label>
            <Textarea
              id="keyMessage"
              name="keyMessage"
              placeholder="What problem does your app solve? What's the main value proposition?"
              defaultValue={initialData?.config.keyMessage || ""}
              rows={3}
              required
            />
          </div>

          <div className="space-y-2">
            <Label>App Screenshots (optional)</Label>
            <p className="text-xs text-muted-foreground">
              Upload screenshots of the feature you want to showcase. These will
              be incorporated into generated ads.
            </p>

            {screenshots.length > 0 && (
              <div className="grid grid-cols-3 gap-2">
                {screenshots.map((s, i) => (
                  <div key={i} className="relative group">
                    <img
                      src={s.preview}
                      alt={s.file?.name || "Screenshot"}
                      className="w-full aspect-[9/19.5] object-cover rounded-md border"
                    />
                    <button
                      type="button"
                      onClick={() => removeScreenshot(i)}
                      className="absolute top-1 right-1 rounded-full bg-black/60 p-0.5 text-white opacity-0 group-hover:opacity-100 transition-opacity"
                    >
                      <X className="h-3.5 w-3.5" />
                    </button>
                    {s.uploadedPath && (
                      <div className="absolute bottom-1 left-1 rounded bg-green-600/80 px-1.5 py-0.5 text-[10px] text-white">
                        Uploaded
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}

            <input
              ref={fileInputRef}
              type="file"
              accept="image/*"
              multiple
              className="hidden"
              onChange={(e) => handleFilesSelected(e.target.files)}
            />

            <button
              type="button"
              onClick={() => fileInputRef.current?.click()}
              onDragOver={(e) => {
                e.preventDefault();
                e.currentTarget.classList.add("border-primary", "bg-primary/5");
              }}
              onDragLeave={(e) => {
                e.currentTarget.classList.remove("border-primary", "bg-primary/5");
              }}
              onDrop={(e) => {
                e.preventDefault();
                e.currentTarget.classList.remove("border-primary", "bg-primary/5");
                handleFilesSelected(e.dataTransfer.files);
              }}
              className="flex w-full items-center justify-center gap-2 rounded-lg border-2 border-dashed border-border px-4 py-6 text-sm text-muted-foreground hover:border-primary hover:bg-primary/5 transition-colors"
            >
              <ImagePlus className="h-5 w-5" />
              <span>Click or drag screenshots here</span>
            </button>
          </div>

          <div className="space-y-2">
            <Label htmlFor="socialProof">Social Proof</Label>
            <Textarea
              id="socialProof"
              name="socialProof"
              placeholder="50K+ downloads, 4.8 star rating, Featured in App Store"
              defaultValue={initialData?.config.socialProof || ""}
              rows={2}
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="targetAudience">Target Audience</Label>
            <Textarea
              id="targetAudience"
              name="targetAudience"
              placeholder="25-35 year old professionals, busy parents, college students..."
              defaultValue={initialData?.config.targetAudience || ""}
              rows={2}
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="visualDirection">Visual Direction</Label>
            <select
              id="visualDirection"
              name="visualDirection"
              className="flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm"
              defaultValue={initialData?.config.visualDirection || "clean"}
            >
              <option value="clean">Clean & Minimal</option>
              <option value="bold">Bold & Vibrant</option>
              <option value="premium">Premium & Dark</option>
              <option value="warm">Warm & Friendly</option>
              <option value="tech">Tech & Modern</option>
            </select>
          </div>

          <div className="space-y-2">
            <Label htmlFor="competitorApps">Competitor Apps (optional)</Label>
            <Input
              id="competitorApps"
              name="competitorApps"
              placeholder="Todoist, Notion, TickTick..."
              defaultValue={initialData?.config.competitorApps || ""}
            />
          </div>

          <div className="space-y-2">
            <Label htmlFor="variations">Variations Per Platform</Label>
            <Input
              id="variations"
              name="variations"
              type="number"
              defaultValue={initialData?.config.variations ?? 5}
              min={1}
              max={20}
            />
          </div>

          <div className="flex items-center gap-2">
            <input
              id="useTrendReport"
              name="useTrendReport"
              type="checkbox"
              className="h-4 w-4 rounded border-input"
              defaultChecked={initialData?.config.useTrendReport || false}
            />
            <Label htmlFor="useTrendReport" className="font-normal">
              Use latest trend report for hook inspiration
            </Label>
          </div>

          {error && (
            <p className="text-sm text-red-500">{error}</p>
          )}

          <Button type="submit" className="w-full" disabled={loading}>
            {loading
              ? mode === "edit" ? "Saving..." : "Creating..."
              : mode === "edit" ? "Save Changes" : "Create Campaign"}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}
