import { useEffect, useRef, useState } from "react";
import { Camera, Loader2, Trash2, Upload } from "lucide-react";
import { toast } from "sonner";
import { removeAvatar, uploadAvatar, type AuthPlatform } from "@/lib/auth";
import { UserAvatar } from "@/components/auth/UserAvatar";
import { Button } from "@/components/ui/button";
import {
  Dialog,
  DialogContent,
  DialogDescription,
  DialogFooter,
  DialogHeader,
  DialogTitle,
} from "@/components/ui/dialog";
import { cn } from "@/lib/utils";

const ACCEPT = "image/jpeg,image/png,image/webp,.jpg,.jpeg,.png,.webp";

export function ProfilePhotoDialog({
  platform,
  open,
  onOpenChange,
  name,
  avatarUrl,
  mode = "change",
}: {
  platform: AuthPlatform;
  open: boolean;
  onOpenChange: (open: boolean) => void;
  name: string;
  avatarUrl?: string | null | undefined;
  mode?: "change" | "remove";
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const previewRef = useRef<string | null>(null);
  const [preview, setPreview] = useState<string | null>(null);
  const [file, setFile] = useState<File | null>(null);
  const [loading, setLoading] = useState(false);
  const [dragging, setDragging] = useState(false);
  const [zoom, setZoom] = useState(1);
  const [confirmRemove, setConfirmRemove] = useState(mode === "remove");

  useEffect(() => {
    if (!open) {
      if (previewRef.current) {
        URL.revokeObjectURL(previewRef.current);
        previewRef.current = null;
      }
      setPreview(null);
      setFile(null);
      setLoading(false);
      setZoom(1);
      setConfirmRemove(mode === "remove");
    } else {
      setConfirmRemove(mode === "remove");
    }
  }, [open, mode]);

  const pickFile = (list: FileList | null) => {
    const next = list?.[0];
    if (!next) return;
    const allowed = ["image/jpeg", "image/jpg", "image/png", "image/webp"];
    if (!allowed.includes(next.type)) {
      toast.error("Please upload a JPG, PNG, or WEBP image");
      return;
    }
    if (next.size > 5 * 1024 * 1024) {
      toast.error("Image must be 5 MB or smaller");
      return;
    }
    if (previewRef.current) URL.revokeObjectURL(previewRef.current);
    const url = URL.createObjectURL(next);
    previewRef.current = url;
    setFile(next);
    setPreview(url);
    setConfirmRemove(false);
    setZoom(1);
  };

  const handleSave = async () => {
    if (!file) return;
    setLoading(true);
    const result = await uploadAvatar(platform, file);
    setLoading(false);
    if (!result.ok) {
      toast.error(result.error);
      return;
    }
    toast.success("Profile photo updated");
    onOpenChange(false);
  };

  const handleRemove = async () => {
    setLoading(true);
    const result = await removeAvatar(platform);
    setLoading(false);
    if (!result.ok) {
      toast.error(result.error);
      return;
    }
    toast.success("Profile photo removed");
    onOpenChange(false);
  };

  return (
    <Dialog open={open} onOpenChange={onOpenChange}>
      <DialogContent className="max-w-md">
        <DialogHeader>
          <DialogTitle>
            {confirmRemove && !preview ? "Remove profile photo?" : "Change profile photo"}
          </DialogTitle>
          <DialogDescription>
            {confirmRemove && !preview
              ? "Your profile picture will be removed and your default avatar will be shown instead."
              : "JPG, PNG or WEBP · max 5 MB"}
          </DialogDescription>
        </DialogHeader>

        {confirmRemove && !preview ? (
          <div className="flex flex-col items-center gap-4 py-2">
            <UserAvatar name={name} avatarUrl={avatarUrl} size="xl" />
            <DialogFooter className="w-full sm:justify-between">
              <Button type="button" variant="outline" onClick={() => onOpenChange(false)} disabled={loading}>
                Cancel
              </Button>
              <Button type="button" variant="destructive" disabled={loading} onClick={() => void handleRemove()}>
                {loading ? (
                  <>
                    <Loader2 className="animate-spin" size={16} />
                    Removing…
                  </>
                ) : (
                  "Remove"
                )}
              </Button>
            </DialogFooter>
          </div>
        ) : preview ? (
          <div className="space-y-4">
            <div className="flex flex-col items-center gap-3">
              <div className="relative size-36 overflow-hidden rounded-full border border-border bg-muted shadow-sm">
                <img
                  src={preview}
                  alt="Preview"
                  className="size-full object-cover"
                  style={{ transform: `scale(${zoom})` }}
                />
              </div>
              <label className="flex w-full max-w-[220px] flex-col gap-1 text-[12px] text-muted-foreground">
                Zoom
                <input
                  type="range"
                  min={1}
                  max={1.8}
                  step={0.05}
                  value={zoom}
                  onChange={(e) => setZoom(Number(e.target.value))}
                  className="w-full accent-[var(--color-brand)]"
                />
              </label>
            </div>
            <DialogFooter className="sm:justify-between">
              <Button
                type="button"
                variant="outline"
                disabled={loading}
                onClick={() => {
                  if (previewRef.current) URL.revokeObjectURL(previewRef.current);
                  previewRef.current = null;
                  setPreview(null);
                  setFile(null);
                }}
              >
                Cancel
              </Button>
              <Button type="button" disabled={loading || !file} onClick={() => void handleSave()}>
                {loading ? (
                  <>
                    <Loader2 className="animate-spin" size={16} />
                    Uploading…
                  </>
                ) : (
                  "Save photo"
                )}
              </Button>
            </DialogFooter>
          </div>
        ) : (
          <div className="space-y-4">
            <div
              className={cn(
                "flex flex-col items-center justify-center rounded-xl border border-dashed px-4 py-10 text-center transition-colors",
                dragging ? "border-brand bg-brand-soft/40" : "border-border bg-muted/30",
              )}
              onDragOver={(e) => {
                e.preventDefault();
                setDragging(true);
              }}
              onDragLeave={() => setDragging(false)}
              onDrop={(e) => {
                e.preventDefault();
                setDragging(false);
                pickFile(e.dataTransfer.files);
              }}
            >
              <span className="flex size-12 items-center justify-center rounded-full bg-brand-soft text-brand-foreground">
                <Camera size={22} aria-hidden="true" />
              </span>
              <p className="mt-3 text-[14px] font-medium text-foreground">Upload photo</p>
              <p className="mt-1 text-[12.5px] text-muted-foreground">
                Drag &amp; drop or choose a file from your device
              </p>
              <Button
                type="button"
                variant="outline"
                className="mt-4 gap-2"
                onClick={() => inputRef.current?.click()}
              >
                <Upload size={15} />
                Choose photo
              </Button>
            </div>
            {avatarUrl ? (
              <Button
                type="button"
                variant="ghost"
                className="w-full gap-2 text-destructive hover:text-destructive"
                onClick={() => setConfirmRemove(true)}
              >
                <Trash2 size={15} />
                Remove current photo
              </Button>
            ) : null}
            <input
              ref={inputRef}
              type="file"
              accept={ACCEPT}
              className="sr-only"
              onChange={(e) => {
                pickFile(e.target.files);
                e.target.value = "";
              }}
            />
          </div>
        )}
      </DialogContent>
    </Dialog>
  );
}
