"use client";

import { useState, useRef } from "react";
import Image from "next/image";
import { useTranslations } from "next-intl";
import { Upload, X, Star } from "lucide-react";
import { Button } from "@/components/ui/button";
import { getPublicUrl } from "@/lib/storage";

export type PhotoEntry = {
  key: string;
  isCover: boolean;
  preview: string;
};

export function PhotoUploader({
  recipeId,
  photos,
  onChange,
}: {
  recipeId: string;
  photos: PhotoEntry[];
  onChange: (photos: PhotoEntry[]) => void;
}) {
  const t = useTranslations("recipeForm");
  const [uploading, setUploading] = useState(false);
  const inputRef = useRef<HTMLInputElement>(null);

  async function handleFiles(files: FileList) {
    setUploading(true);
    try {
      // Accumulate locally instead of calling onChange(...photos, entry) per file —
      // `photos` is a stale closure over the prop from when handleFiles was called,
      // so multiple onChange calls in this loop would each overwrite the previous
      // one's addition instead of stacking (only the last uploaded file would stick).
      let next = photos;
      for (const file of Array.from(files)) {
        const res = await fetch("/api/v1/upload/presign", {
          method: "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify({ recipeId, contentType: file.type, fileSize: file.size }),
        });
        if (!res.ok) continue;
        const { url, key } = await res.json() as { url: string; key: string };
        await fetch(url, { method: "PUT", body: file, headers: { "Content-Type": file.type } });
        const isFirst = next.length === 0;
        next = [...next, { key, isCover: isFirst, preview: URL.createObjectURL(file) }];
        onChange(next);
      }
    } finally {
      setUploading(false);
    }
  }

  function setCover(key: string) {
    onChange(photos.map((p) => ({ ...p, isCover: p.key === key })));
  }

  function remove(key: string) {
    const filtered = photos.filter((p) => p.key !== key);
    if (filtered.length > 0 && !filtered.some((p) => p.isCover)) {
      filtered[0]!.isCover = true;
    }
    onChange(filtered);
  }

  return (
    <div className="space-y-3">
      <div className="flex flex-wrap gap-3">
        {photos.map((photo) => (
          <div key={photo.key} className="relative group h-24 w-24">
            <Image
              src={photo.preview || getPublicUrl(photo.key)}
              unoptimized
              alt="Recipe photo"
              fill
              className={`rounded-lg object-cover border-2 ${
                photo.isCover ? "border-primary" : "border-transparent"
              }`}
            />
            <div className="absolute inset-0 bg-black/40 opacity-0 group-hover:opacity-100 rounded-lg transition-opacity flex items-center justify-center gap-1">
              <button
                type="button"
                onClick={() => setCover(photo.key)}
                className="rounded-full bg-white/20 p-1 hover:bg-white/40 transition-colors"
                title={t("setCover")}
              >
                <Star className={`h-3 w-3 ${photo.isCover ? "text-yellow-400" : "text-white"}`} />
              </button>
              <button
                type="button"
                onClick={() => remove(photo.key)}
                className="rounded-full bg-white/20 p-1 hover:bg-red-500/80 transition-colors"
                title={t("removePhoto")}
              >
                <X className="h-3 w-3 text-white" />
              </button>
            </div>
            {photo.isCover && (
              <span className="absolute bottom-1 left-1 text-[10px] bg-primary text-primary-foreground rounded px-1">
                cover
              </span>
            )}
          </div>
        ))}

        <button
          type="button"
          onClick={() => inputRef.current?.click()}
          disabled={uploading}
          className="h-24 w-24 rounded-lg border-2 border-dashed border-muted-foreground/25 hover:border-muted-foreground/50 flex flex-col items-center justify-center gap-1 text-muted-foreground transition-colors disabled:opacity-50"
        >
          <Upload className="h-4 w-4" />
          <span className="text-xs">{uploading ? "Uploading…" : "Add photo"}</span>
        </button>
      </div>

      <input
        ref={inputRef}
        type="file"
        accept="image/jpeg,image/png,image/webp,image/avif"
        multiple
        className="hidden"
        onChange={(e) => e.target.files && handleFiles(e.target.files)}
      />
    </div>
  );
}
