"use client";

import { useState } from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
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 {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
} from "@/components/ui/dialog";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { createShot } from "@/actions/shots";
import { useToast } from "@/components/ui/use-toast";

const shotSchema = z.object({
  scene: z.string().min(1, "Scene is required").max(50).regex(/^[A-Z0-9_]+$/i, "Alphanumeric and underscore only"),
  episode: z.string().max(50).optional(),
  shotGroupName: z.string().max(100).optional(),
  description: z.string().optional(),
  priority: z.enum(["LOW", "NORMAL", "HIGH", "URGENT"]),
  fps: z.coerce.number().min(1).max(120),
});

type ShotFormValues = z.infer<typeof shotSchema>;

interface NewShotDialogProps {
  projectId: string;
  projectType?: "STANDARD" | "EPISODIC";
  shotGroups?: { id: string; name: string }[];
  open: boolean;
  onClose: () => void;
  onSuccess?: () => void;
}

export function NewShotDialog({ projectId, projectType = "STANDARD", shotGroups = [], open, onClose, onSuccess }: NewShotDialogProps) {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
  const [thumbnailPreview, setThumbnailPreview] = useState<string | null>(null);
  const { toast } = useToast();
  const router = useRouter();
  const isEpisodic = projectType === "EPISODIC";

  const {
    register,
    handleSubmit,
    setValue,
    reset,
    formState: { errors },
  } = useForm<ShotFormValues>({
    resolver: zodResolver(shotSchema),
    defaultValues: { priority: "NORMAL", fps: 24 },
  });

  const handleThumbnailChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target.files?.[0];
    if (file) {
      setThumbnailFile(file);
      const reader = new FileReader();
      reader.onload = (event) => {
        setThumbnailPreview(event.target?.result as string);
      };
      reader.readAsDataURL(file);
    }
  };

  const onSubmit = async (data: ShotFormValues) => {
    setIsSubmitting(true);
    try {
      let thumbnailUrl: string | undefined;

      // Upload thumbnail if provided
      if (thumbnailFile) {
        const formData = new FormData();
        formData.append("file", thumbnailFile);
        formData.append("type", "image");

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

        if (!uploadRes.ok) {
          throw new Error("Failed to upload thumbnail");
        }

        const uploadData = await uploadRes.json();
        thumbnailUrl = uploadData.url;
      }

      await createShot({ projectId, ...data, thumbnailUrl });
      toast({ title: "Shot created" });
      reset();
      setThumbnailFile(null);
      setThumbnailPreview(null);
      router.refresh();
      onSuccess?.();
      onClose();
    } catch (err) {
      toast({
        title: "Failed to create shot",
        description: (err as Error).message,
        variant: "destructive",
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <Dialog open={open} onOpenChange={(o) => !o && onClose()}>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>New Shot</DialogTitle>
        </DialogHeader>

        <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
          <div className={`grid gap-3 ${isEpisodic ? "grid-cols-2" : "grid-cols-1"}`}>
            {isEpisodic && (
              <div className="space-y-1.5">
                <Label htmlFor="episode">Episode *</Label>
                <Input
                  id="episode"
                  placeholder="EP01"
                  {...register("episode")}
                  className="uppercase"
                />
                {errors.episode && (
                  <p className="text-xs text-destructive">{errors.episode.message}</p>
                )}
              </div>
            )}
            <div className="space-y-1.5">
              <Label htmlFor="scene">Scene *</Label>
              <Input
                id="scene"
                placeholder="SC010"
                {...register("scene")}
                className="uppercase"
              />
              {errors.scene && (
                <p className="text-xs text-destructive">{errors.scene.message}</p>
              )}
            </div>
          </div>

          <p className="text-xs text-muted-foreground">
            Shot code will be auto-generated (e.g.{" "}
            {isEpisodic ? "SHOW_EP01_SC010_0010" : "SHOW_SC010_0010"})
          </p>

          <div className="space-y-1.5">
            <Label htmlFor="shotGroupName">Group <span className="text-muted-foreground font-normal">(optional)</span></Label>
            <Input
              id="shotGroupName"
              list="shot-group-suggestions"
              placeholder={shotGroups.length > 0 ? "Choose or type a new group" : "e.g. Action Sequences"}
              {...register("shotGroupName")}
            />
            {shotGroups.length > 0 && (
              <datalist id="shot-group-suggestions">
                {shotGroups.map((g) => (
                  <option key={g.id} value={g.name} />
                ))}
              </datalist>
            )}
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="description">Description</Label>
            <Textarea
              id="description"
              placeholder="What happens in this shot?"
              {...register("description")}
              className="min-h-[70px]"
            />
          </div>

          <div className="space-y-1.5">
            <Label htmlFor="thumbnail">Thumbnail (optional)</Label>
            <Input
              id="thumbnail"
              type="file"
              accept="image/*"
              onChange={handleThumbnailChange}
              className="cursor-pointer"
            />
            {thumbnailPreview && (
              <div className="relative w-full aspect-[2.39] rounded-lg overflow-hidden border border-border">
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={thumbnailPreview}
                  alt="Thumbnail preview"
                  className="w-full h-full object-cover"
                />
              </div>
            )}
          </div>

          <div className="grid grid-cols-3 gap-3">
            <div className="space-y-1.5 col-span-2">
              <Label>Priority</Label>
              <Select
                defaultValue="NORMAL"
                onValueChange={(v) => setValue("priority", v as any)}
              >
                <SelectTrigger>
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="LOW">Low</SelectItem>
                  <SelectItem value="NORMAL">Normal</SelectItem>
                  <SelectItem value="HIGH">High</SelectItem>
                  <SelectItem value="URGENT">Urgent</SelectItem>
                </SelectContent>
              </Select>
            </div>

            <div className="space-y-1.5">
              <Label htmlFor="fps">FPS</Label>
              <Input
                id="fps"
                type="number"
                placeholder="24"
                {...register("fps")}
              />
            </div>
          </div>

          <DialogFooter>
            <Button type="button" variant="outline" onClick={onClose}>
              Cancel
            </Button>
            <Button type="submit" disabled={isSubmitting}>
              {isSubmitting ? "Creating..." : "Create Shot"}
            </Button>
          </DialogFooter>
        </form>
      </DialogContent>
    </Dialog>
  );
}
