﻿"use client";

import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";
import {
  Dialog,
  DialogContent,
  DialogHeader,
  DialogTitle,
  DialogFooter,
  DialogTrigger,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Button } from "@/components/ui/button";
import { useToast } from "@/components/ui/use-toast";
import { Copy, Check, ExternalLink, Eye, EyeOff, Lock, Film } from "lucide-react";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";
import { cn } from "@/lib/utils";

const schema = z.object({
  projectId: z.string().min(1, "Select a project"),
  label: z.string().min(1, "Label is required"),
  email: z.string().email("Invalid email"),
  expiresInDays: z.number().int().positive().default(30),
  password: z.string().optional(),
});

type FormValues = z.infer<typeof schema>;

interface Project {
  id: string;
  name: string;
  code: string;
}

interface ShareReviewDialogProps {
  children: React.ReactNode;
  clientId: string;
  clientEmail: string;
  projects: Project[];
}

export function ShareReviewDialog({
  children,
  clientEmail,
  projects,
}: ShareReviewDialogProps) {
  const [open, setOpen] = useState(false);
  const [loading, setLoading] = useState(false);
  const [portalUrl, setPortalUrl] = useState<string | null>(null);
  const [isPasswordProtected, setIsPasswordProtected] = useState(false);
  const [copied, setCopied] = useState(false);
  const [showPassword, setShowPassword] = useState(false);
  const [episodes, setEpisodes] = useState<string[]>([]);
  const [selectedEpisodes, setSelectedEpisodes] = useState<string[]>([]);
  const [loadingEpisodes, setLoadingEpisodes] = useState(false);
  const { toast } = useToast();
  const router = useRouter();

  const {
    register,
    handleSubmit,
    watch,
    setValue,
    reset,
    formState: { errors },
  } = useForm<FormValues>({
    resolver: zodResolver(schema),
    defaultValues: {
      projectId: projects[0]?.id ?? "",
      label: "Review Round 1",
      email: clientEmail,
      expiresInDays: 30,
      password: "",
    },
  });

  const selectedProjectId = watch("projectId");

  // Load episodes when project changes
  useEffect(() => {
    if (!selectedProjectId) return;
    setSelectedEpisodes([]);
    setLoadingEpisodes(true);
    fetch(`/api/projects/${selectedProjectId}/episodes`)
      .then((r) => r.json())
      .then((data) => setEpisodes(data.episodes ?? []))
      .catch(() => setEpisodes([]))
      .finally(() => setLoadingEpisodes(false));
  }, [selectedProjectId]);

  const toggleEpisode = (ep: string) => {
    setSelectedEpisodes((prev) =>
      prev.includes(ep) ? prev.filter((e) => e !== ep) : [...prev, ep]
    );
  };

  const handleCopy = async () => {
    if (!portalUrl) return;
    await navigator.clipboard.writeText(portalUrl);
    setCopied(true);
    setTimeout(() => setCopied(false), 2000);
  };

  const handleReset = () => {
    setPortalUrl(null);
    setIsPasswordProtected(false);
    setSelectedEpisodes([]);
    reset({
      projectId: projects[0]?.id ?? "",
      label: "Review Round 1",
      email: clientEmail,
      expiresInDays: 30,
      password: "",
    });
  };

  const onSubmit = async (values: FormValues) => {
    setLoading(true);
    try {
      const res = await fetch("/api/review-sessions", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          ...values,
          password: values.password?.trim() || undefined,
          allowedEpisodes: selectedEpisodes.length > 0 ? selectedEpisodes : [],
        }),
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        throw new Error(err.error ?? "Failed to create review link");
      }
      const data = await res.json();
      setPortalUrl(data.portalUrl);
      setIsPasswordProtected(!!(values.password?.trim()));
      router.refresh();
    } catch (e) {
      toast({
        title: "Failed to create review link",
        description: e instanceof Error ? e.message : undefined,
        variant: "destructive",
      });
    } finally {
      setLoading(false);
    }
  };

  return (
    <Dialog
      open={open}
      onOpenChange={(o) => {
        if (!o) { setPortalUrl(null); }
        setOpen(o);
      }}
    >
      <DialogTrigger asChild>{children}</DialogTrigger>
      <DialogContent className="sm:max-w-md">
        <DialogHeader>
          <DialogTitle>Share Review Link</DialogTitle>
        </DialogHeader>

        {portalUrl ? (
          <div className="space-y-4">
            <p className="text-sm text-zinc-400">
              Your review link is ready. Copy it and share it with your client.
            </p>
            {isPasswordProtected && (
              <div className="flex items-center gap-2 px-3 py-2 rounded-lg bg-amber-500/10 border border-amber-500/20 text-amber-400 text-xs">
                <Lock className="h-3.5 w-3.5 shrink-0" />
                This link is password protected. Share the password separately.
              </div>
            )}
            {selectedEpisodes.length > 0 && (
              <div className="flex items-start gap-2 px-3 py-2 rounded-lg bg-violet-500/10 border border-violet-500/20 text-violet-300 text-xs">
                <Film className="h-3.5 w-3.5 shrink-0 mt-0.5" />
                <span>Scoped to {selectedEpisodes.length === 1 ? "episode" : "episodes"}: <span className="font-medium">{selectedEpisodes.join(", ")}</span></span>
              </div>
            )}
            <div className="flex items-center gap-2 p-3 rounded-lg bg-zinc-800 border border-zinc-700">
              <ExternalLink className="h-4 w-4 text-zinc-500 shrink-0" />
              <span className="flex-1 text-sm font-mono text-zinc-300 truncate">{portalUrl}</span>
              <Button
                size="sm"
                variant="outline"
                className="h-7 px-2.5 gap-1.5 shrink-0"
                onClick={handleCopy}
              >
                {copied ? (
                  <Check className="h-3.5 w-3.5 text-emerald-400" />
                ) : (
                  <Copy className="h-3.5 w-3.5" />
                )}
                {copied ? "Copied!" : "Copy"}
              </Button>
            </div>
            <DialogFooter className="flex gap-2">
              <Button variant="outline" onClick={handleReset}>
                Create Another
              </Button>
              <Button onClick={() => setOpen(false)}>Done</Button>
            </DialogFooter>
          </div>
        ) : (
          <form onSubmit={handleSubmit(onSubmit)} className="space-y-4">
            <div className="space-y-1.5">
              <Label htmlFor="projectId">Project *</Label>
              <Select
                defaultValue={watch("projectId")}
                onValueChange={(v) => setValue("projectId", v)}
              >
                <SelectTrigger id="projectId">
                  <SelectValue placeholder="Select project" />
                </SelectTrigger>
                <SelectContent>
                  {projects.map((p) => (
                    <SelectItem key={p.id} value={p.id}>
                      {p.name} <span className="text-zinc-500 text-xs ml-1">({p.code})</span>
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
              {errors.projectId && <p className="text-xs text-red-400">{errors.projectId.message}</p>}
            </div>

            {/* Episode filter â€” only shown when the project has episodes */}
            {!loadingEpisodes && episodes.length > 0 && (
              <div className="space-y-1.5">
                <Label className="flex items-center gap-1.5">
                  <Film className="h-3.5 w-3.5 text-zinc-400" />
                  Episodes <span className="text-zinc-500 font-normal">(optional â€” leave blank for all)</span>
                </Label>
                <div className="flex flex-wrap gap-1.5 p-2.5 rounded-lg border border-zinc-700 bg-zinc-900">
                  {episodes.map((ep) => {
                    const active = selectedEpisodes.includes(ep);
                    return (
                      <button
                        key={ep}
                        type="button"
                        onClick={() => toggleEpisode(ep)}
                        className={cn(
                          "px-2.5 py-1 rounded-md text-xs font-medium transition-colors border",
                          active
                            ? "bg-violet-600 border-violet-500 text-white"
                            : "bg-zinc-800 border-zinc-700 text-zinc-300 hover:border-zinc-500"
                        )}
                      >
                        {ep}
                      </button>
                    );
                  })}
                </div>
                {selectedEpisodes.length > 0 && (
                  <p className="text-xs text-zinc-500">
                    Showing shots from: <span className="text-zinc-300">{selectedEpisodes.join(", ")}</span>
                  </p>
                )}
              </div>
            )}

            <div className="space-y-1.5">
              <Label htmlFor="label">Label *</Label>
              <Input id="label" placeholder="e.g. Review Round 1" {...register("label")} />
              {errors.label && <p className="text-xs text-red-400">{errors.label.message}</p>}
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="email">Client Email *</Label>
              <Input id="email" type="email" {...register("email")} />
              {errors.email && <p className="text-xs text-red-400">{errors.email.message}</p>}
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="expiresInDays">Expires In (days)</Label>
              <Select
                defaultValue={String(watch("expiresInDays"))}
                onValueChange={(v) => setValue("expiresInDays", Number(v))}
              >
                <SelectTrigger id="expiresInDays">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {[7, 14, 30, 60, 90].map((d) => (
                    <SelectItem key={d} value={String(d)}>
                      {d} days
                    </SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </div>
            <div className="space-y-1.5">
              <Label htmlFor="password" className="flex items-center gap-1.5">
                <Lock className="h-3.5 w-3.5 text-zinc-400" />
                Password <span className="text-zinc-500 font-normal">(optional)</span>
              </Label>
              <div className="relative">
                <Input
                  id="password"
                  type={showPassword ? "text" : "password"}
                  placeholder="Leave blank for no password"
                  className="pr-9"
                  {...register("password")}
                />
                <button
                  type="button"
                  className="absolute right-2.5 top-1/2 -translate-y-1/2 text-zinc-400 hover:text-zinc-200 transition-colors"
                  onClick={() => setShowPassword((v) => !v)}
                  tabIndex={-1}
                >
                  {showPassword ? (
                    <EyeOff className="h-4 w-4" />
                  ) : (
                    <Eye className="h-4 w-4" />
                  )}
                </button>
              </div>
            </div>
            <DialogFooter>
              <Button type="button" variant="outline" onClick={() => setOpen(false)}>
                Cancel
              </Button>
              <Button type="submit" disabled={loading || projects.length === 0}>
                {loading ? "Generating..." : "Create Link"}
              </Button>
            </DialogFooter>
          </form>
        )}
      </DialogContent>
    </Dialog>
  );
}
