﻿"use client";

import { useState, useRef } from "react";
import Image from "next/image";
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 { Separator } from "@/components/ui/separator";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { updateShot } from "@/actions/shots";
import { useToast } from "@/components/ui/use-toast";
import { Upload, X, Film, ImageIcon, Video } from "lucide-react";

const settingsSchema = z.object({
  description: z.string().optional(),
  status: z.enum(["WAITING", "IN_PROGRESS", "IN_REVIEW", "REVISIONS", "COMPLETE"]),
  priority: z.enum(["LOW", "NORMAL", "HIGH", "URGENT"]),
  fps: z.coerce.number().min(1).max(240),
  frameStart: z.coerce.number().int().optional().or(z.literal("")),
  frameEnd: z.coerce.number().int().optional().or(z.literal("")),
  dueDate: z.string().optional(),
  artistId: z.string().optional(),
});

type SettingsFormValues = z.infer<typeof settingsSchema>;

interface Artist {
  id: string;
  name: string | null;
  email: string;
}

interface ShotSettingsTabProps {
  shot: {
    id: string;
    shotCode: string;
    description: string | null;
    status: string;
    priority: string;
    fps: number;
    frameStart?: number | null;
    frameEnd?: number | null;
    dueDate: Date | string | null;
    artistId: string | null;
    thumbnailUrl: string | null;
    originalFootageUrl: string | null;
    originalFootageKey: string | null;
  };
  artists: Artist[];
  onSaved?: () => void;
}

function uploadViaXhr(
  file: File,
  onProgress: (fraction: number) => void
): Promise<{ url: string; key: string }> {
  return new Promise((resolve, reject) => {
    const formData = new FormData();
    formData.append("file", file);

    const xhr = new XMLHttpRequest();
    xhr.open("POST", "/api/upload/local");

    xhr.upload.addEventListener("progress", (e) => {
      if (e.lengthComputable) onProgress(e.loaded / e.total);
    });

    xhr.addEventListener("load", () => {
      if (xhr.status >= 200 && xhr.status < 300) {
        try {
          const json = JSON.parse(xhr.responseText);
          if (json.url) resolve({ url: json.url, key: json.key ?? "" });
          else reject(new Error(json.error ?? "Upload failed"));
        } catch {
          reject(new Error("Invalid server response"));
        }
      } else {
        try {
          const json = JSON.parse(xhr.responseText);
          reject(new Error(json.error ?? `HTTP ${xhr.status}`));
        } catch {
          reject(new Error(`HTTP ${xhr.status}`));
        }
      }
    });

    xhr.addEventListener("error", () => reject(new Error("Network error")));
    xhr.addEventListener("abort", () => reject(new Error("Upload aborted")));
    xhr.send(formData);
  });
}

export function ShotSettingsTab({ shot, artists, onSaved }: ShotSettingsTabProps) {
  const { toast } = useToast();
  const [isSaving, setIsSaving] = useState(false);
  const [thumbnailFile, setThumbnailFile] = useState<File | null>(null);
  const [thumbnailPreview, setThumbnailPreview] = useState<string | null>(shot.thumbnailUrl ?? null);
  const [clearThumbnail, setClearThumbnail] = useState(false);
  const fileInputRef = useRef<HTMLInputElement>(null);

  // Footage upload state
  const [footageFile, setFootageFile] = useState<File | null>(null);
  const [footageUploading, setFootageUploading] = useState(false);
  const [footageProgress, setFootageProgress] = useState(0);
  const [currentFootageUrl, setCurrentFootageUrl] = useState<string | null>(shot.originalFootageUrl ?? null);
  const footageInputRef = useRef<HTMLInputElement>(null);

  const formatDate = (d: Date | string | null) => {
    if (!d) return "";
    return new Date(d).toISOString().split("T")[0];
  };

  const {
    register,
    handleSubmit,
    setValue,
    formState: { errors },
  } = useForm<SettingsFormValues>({
    resolver: zodResolver(settingsSchema),
    defaultValues: {
      description: shot.description ?? "",
      status: shot.status as SettingsFormValues["status"],
      priority: shot.priority as SettingsFormValues["priority"],
      fps: shot.fps,
      frameStart: shot.frameStart ?? "",
      frameEnd: shot.frameEnd ?? "",
      dueDate: formatDate(shot.dueDate),
      artistId: shot.artistId ?? "__none__",
    },
  });

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

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

  const handleFootageUpload = async () => {
    if (!footageFile) return;
    setFootageUploading(true);
    setFootageProgress(0);
    try {
      const { url, key } = await uploadViaXhr(footageFile, setFootageProgress);
      await updateShot({
        shotId: shot.id,
        originalFootageUrl: url,
        originalFootageKey: key || undefined,
      });
      setCurrentFootageUrl(url);
      setFootageFile(null);
      toast({ title: "Footage uploaded" });
      onSaved?.();
    } catch (e) {
      toast({ title: "Upload failed", description: e instanceof Error ? e.message : undefined, variant: "destructive" });
    } finally {
      setFootageUploading(false);
      setFootageProgress(0);
    }
  };

  const handleFootageRemove = async () => {
    try {
      await updateShot({ shotId: shot.id, originalFootageUrl: null, originalFootageKey: null });
      setCurrentFootageUrl(null);
      setFootageFile(null);
      toast({ title: "Footage removed" });
      onSaved?.();
    } catch (e) {
      toast({ title: "Failed to remove footage", description: e instanceof Error ? e.message : undefined, variant: "destructive" });
    }
  };

  const onSubmit = async (values: SettingsFormValues) => {
    setIsSaving(true);
    try {
      let thumbnailUrl: string | null | undefined = undefined;

      if (clearThumbnail) {
        thumbnailUrl = null;
      } else if (thumbnailFile) {
        const fd = new FormData();
        fd.append("file", thumbnailFile);
        fd.append("type", "image");
        const res = await fetch("/api/upload", { method: "POST", body: fd });
        if (!res.ok) throw new Error("Thumbnail upload failed");
        const data = await res.json();
        thumbnailUrl = data.url;
      }

      await updateShot({
        shotId: shot.id,
        description: values.description || undefined,
        status: values.status,
        priority: values.priority,
        fps: values.fps,
        frameStart: values.frameStart !== "" && values.frameStart != null ? Number(values.frameStart) : null,
        frameEnd: values.frameEnd !== "" && values.frameEnd != null ? Number(values.frameEnd) : null,
        dueDate: values.dueDate || null,
        artistId: values.artistId === "__none__" ? null : values.artistId,
        thumbnailUrl,
      });

      toast({ title: "Shot updated" });
      onSaved?.();
    } catch (e) {
      toast({ title: "Failed to save", description: e instanceof Error ? e.message : undefined, variant: "destructive" });
    } finally {
      setIsSaving(false);
    }
  };

  return (
    <div className="space-y-10 max-w-2xl">
    <form onSubmit={handleSubmit(onSubmit)} className="space-y-8">
      {/* Details */}
      <div className="space-y-4">
        <div className="flex items-center gap-2 text-sm font-semibold text-zinc-300">
          <Film className="h-4 w-4 text-amber-500" />
          Details
        </div>
        <Separator />

        <div className="space-y-1.5">
          <Label>Description</Label>
          <Textarea {...register("description")} rows={3} placeholder="Shot descriptionâ€¦" />
        </div>

        <div className="grid grid-cols-2 gap-4">
          <div className="space-y-1.5">
            <Label>Status</Label>
            <Select
              defaultValue={shot.status}
              onValueChange={(v) => setValue("status", v as SettingsFormValues["status"])}
            >
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>
                <SelectItem value="WAITING">Waiting</SelectItem>
                <SelectItem value="IN_PROGRESS">In Progress</SelectItem>
                <SelectItem value="IN_REVIEW">In Review</SelectItem>
                <SelectItem value="REVISIONS">Revisions</SelectItem>
                <SelectItem value="COMPLETE">Complete</SelectItem>
              </SelectContent>
            </Select>
          </div>

          <div className="space-y-1.5">
            <Label>Priority</Label>
            <Select
              defaultValue={shot.priority}
              onValueChange={(v) => setValue("priority", v as SettingsFormValues["priority"])}
            >
              <SelectTrigger><SelectValue /></SelectTrigger>
              <SelectContent>
                <SelectItem value="LOW">Low</SelectItem>
                <SelectItem value="NORMAL">Normal</SelectItem>
                <SelectItem value="HIGH">High</SelectItem>
                <SelectItem value="CRITICAL">Critical</SelectItem>
              </SelectContent>
            </Select>
          </div>
        </div>
      </div>

      {/* Timing */}
      <div className="space-y-4">
        <div className="flex items-center gap-2 text-sm font-semibold text-zinc-300">
          <span className="text-amber-500 font-mono text-xs">FPS</span>
          Timing
        </div>
        <Separator />

        <div className="grid grid-cols-3 gap-4">
          <div className="space-y-1.5">
            <Label>FPS</Label>
            <Input type="number" step="any" {...register("fps")} />
            {errors.fps && <p className="text-xs text-destructive">{errors.fps.message}</p>}
          </div>
          <div className="space-y-1.5">
            <Label>Frame Start</Label>
            <Input type="number" {...register("frameStart")} placeholder="1001" />
          </div>
          <div className="space-y-1.5">
            <Label>Frame End</Label>
            <Input type="number" {...register("frameEnd")} placeholder="1100" />
          </div>
        </div>

        <div className="space-y-1.5 max-w-xs">
          <Label>Due Date</Label>
          <Input type="date" {...register("dueDate")} />
        </div>
      </div>

      {/* Assignment */}
      <div className="space-y-4">
        <div className="flex items-center gap-2 text-sm font-semibold text-zinc-300">
          <span className="text-amber-500">ðŸ‘¤</span>
          Assignment
        </div>
        <Separator />

        <div className="space-y-1.5 max-w-xs">
          <Label>Artist</Label>
          <Select
            defaultValue={shot.artistId ?? "__none__"}
            onValueChange={(v) => setValue("artistId", v)}
          >
            <SelectTrigger><SelectValue placeholder="Unassigned" /></SelectTrigger>
            <SelectContent>
              <SelectItem value="__none__">Unassigned</SelectItem>
              {artists.map((a) => (
                <SelectItem key={a.id} value={a.id}>
                  {a.name ?? a.email}
                </SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
      </div>

      {/* Thumbnail */}
      <div className="space-y-4">
        <div className="flex items-center gap-2 text-sm font-semibold text-zinc-300">
          <ImageIcon className="h-4 w-4 text-amber-500" />
          Thumbnail
        </div>
        <Separator />

        {thumbnailPreview && !clearThumbnail ? (
          <div className="relative w-72 aspect-[2.39] rounded-lg overflow-hidden border border-border group">
            <Image src={thumbnailPreview} alt={shot.shotCode} fill className="object-cover" />
            <button
              type="button"
              onClick={() => { setClearThumbnail(true); setThumbnailPreview(null); setThumbnailFile(null); }}
              className="absolute top-1.5 right-1.5 bg-black/70 hover:bg-black text-white rounded-full p-0.5 opacity-0 group-hover:opacity-100 transition-opacity"
            >
              <X className="h-3.5 w-3.5" />
            </button>
          </div>
        ) : (
          <div
            onClick={() => fileInputRef.current?.click()}
            className="w-72 aspect-[2.39] rounded-lg border-2 border-dashed border-border hover:border-amber-500/50 flex items-center justify-center gap-2 text-sm text-muted-foreground cursor-pointer transition-colors"
          >
            <Upload className="h-4 w-4" />
            Upload thumbnail
          </div>
        )}
        <input
          ref={fileInputRef}
          type="file"
          accept="image/*"
          className="hidden"
          onChange={handleThumbnailChange}
        />
      </div>

      <Button type="submit" disabled={isSaving}>
        {isSaving ? "Savingâ€¦" : "Save Changes"}
      </Button>
    </form>

    {/* Original Footage â€” separate section with its own XHR upload */}
    <div className="space-y-4">
      <div className="flex items-center gap-2 text-sm font-semibold text-zinc-300">
        <Video className="h-4 w-4 text-amber-500" />
        Original Footage
      </div>
      <Separator />
      <p className="text-xs text-zinc-500">Upload the original (pre-VFX) footage for reference. Supported formats: MP4, MOV, AVI, MKV, WebM.</p>

      {currentFootageUrl ? (
        <div className="flex items-center gap-3 p-3 rounded-lg bg-zinc-900 border border-zinc-800">
          <Video className="h-5 w-5 text-amber-400 shrink-0" />
          <span className="text-sm text-zinc-300 truncate flex-1">Footage uploaded</span>
          <div className="flex items-center gap-2 shrink-0">
            <Button
              type="button"
              variant="outline"
              size="sm"
              onClick={() => footageInputRef.current?.click()}
            >
              Replace
            </Button>
            <Button
              type="button"
              variant="ghost"
              size="sm"
              className="text-zinc-500 hover:text-red-400"
              onClick={handleFootageRemove}
            >
              <X className="h-4 w-4" />
            </Button>
          </div>
        </div>
      ) : (
        <div
          onClick={() => !footageUploading && footageInputRef.current?.click()}
          className="w-full rounded-lg border-2 border-dashed border-border hover:border-amber-500/50 flex flex-col items-center justify-center gap-2 py-8 text-sm text-muted-foreground cursor-pointer transition-colors"
        >
          <Video className="h-6 w-6" />
          <span>Click to select original footage</span>
        </div>
      )}

      {footageFile && !footageUploading && (
        <div className="flex items-center gap-3 p-3 rounded-lg bg-zinc-900 border border-zinc-800">
          <Video className="h-5 w-5 text-zinc-400 shrink-0" />
          <span className="text-sm text-zinc-300 truncate flex-1">{footageFile.name}</span>
          <span className="text-xs text-zinc-500 shrink-0">{(footageFile.size / 1024 / 1024).toFixed(1)} MB</span>
          <Button type="button" size="sm" onClick={handleFootageUpload}>
            Upload
          </Button>
          <button
            type="button"
            onClick={() => setFootageFile(null)}
            className="text-zinc-500 hover:text-zinc-300"
          >
            <X className="h-4 w-4" />
          </button>
        </div>
      )}

      {footageUploading && (
        <div className="space-y-2">
          <div className="flex items-center justify-between text-xs text-zinc-400">
            <span>Uploadingâ€¦</span>
            <span>{Math.round(footageProgress * 100)}%</span>
          </div>
          <div className="h-1.5 bg-zinc-800 rounded-full overflow-hidden">
            <div
              className="h-full bg-amber-500 transition-all duration-200"
              style={{ width: `${footageProgress * 100}%` }}
            />
          </div>
        </div>
      )}

      <input
        ref={footageInputRef}
        type="file"
        accept="video/mp4,video/quicktime,video/x-msvideo,video/x-matroska,video/webm,video/*"
        className="hidden"
        onChange={handleFootageChange}
      />
    </div>
    </div>
  );
}
