"use client";

import Image from "next/image";
import { ImagePlus, Loader2 } from "lucide-react";
import { useEffect, useId, useState } from "react";
import { cn } from "@/lib/utils";

type AdminImageUploadProps = {
  label: string;
  name?: string;
  defaultValue?: string;
  value?: string;
  onChange?: (url: string) => void;
  required?: boolean;
  previewAlt?: string;
  className?: string;
  allowDelete?: boolean;
};

export function AdminImageUpload({
  label,
  name,
  defaultValue = "",
  value,
  onChange,
  required,
  previewAlt = "Uploaded image preview",
  className,
  allowDelete = true,
}: AdminImageUploadProps) {
  const inputId = useId();
  const [imageUrl, setImageUrl] = useState(value ?? defaultValue);
  const [status, setStatus] = useState("");
  const [isUploading, setIsUploading] = useState(false);

  useEffect(() => {
    if (value !== undefined) {
      setImageUrl(value);
    }
  }, [value]);

  async function uploadImage(file: File) {
    const body = new FormData();
    body.append("file", file);
    setIsUploading(true);
    setStatus("");

    try {
      const response = await fetch("/api/admin/upload", {
        method: "POST",
        body,
      });
      const result = (await response.json()) as { ok?: boolean; url?: string; message?: string };

      if (!response.ok || !result.ok || !result.url) {
        throw new Error(result.message || "Upload failed.");
      }

      setImageUrl(result.url);
      onChange?.(result.url);
      setStatus("Image uploaded.");
    } catch (error) {
      setStatus(error instanceof Error ? error.message : "Upload failed.");
    } finally {
      setIsUploading(false);
    }
  }

  function clearImage() {
    setImageUrl("");
    onChange?.("");
    setStatus("Image removed.");
  }

  return (
    <div className={cn("rounded-xl border border-border bg-white p-3", className)}>
      {name ? <input name={name} type="hidden" value={imageUrl} required={required} readOnly /> : null}
      <div className="flex items-center justify-between gap-3">
        <div>
          <p className="text-sm font-bold text-navy-deep">{label}</p>
          <p className="mt-1 text-xs text-navy-muted">Upload JPG, PNG, WebP, or GIF.</p>
        </div>
        <input
          id={inputId}
          className="sr-only"
          type="file"
          accept="image/jpeg,image/png,image/webp,image/gif"
          onChange={(event) => {
            const file = event.target.files?.[0];
            if (file) {
              void uploadImage(file);
            }
            event.currentTarget.value = "";
          }}
        />
        <label
          className="inline-flex h-9 shrink-0 cursor-pointer items-center justify-center gap-2 rounded-lg border border-primary/30 bg-white px-3 text-sm font-semibold text-primary-deep transition hover:border-primary hover:bg-primary-soft"
          htmlFor={inputId}
        >
          {isUploading ? <Loader2 className="h-4 w-4 animate-spin" /> : <ImagePlus className="h-4 w-4" />}
          {isUploading ? "Uploading" : "Upload"}
        </label>
      </div>
      {imageUrl ? (
        <div className="mt-3 overflow-hidden rounded-lg border border-border bg-primary-soft/40">
          <Image
            src={imageUrl}
            alt={previewAlt}
            width={420}
            height={240}
            className="h-36 w-full object-cover"
          />
          <p className="truncate border-t border-border bg-white px-3 py-2 text-xs text-navy-muted">{imageUrl}</p>
          {allowDelete ? (
            <div className="border-t border-border bg-white px-3 py-2">
              <button
                type="button"
                onClick={clearImage}
                className="inline-flex h-8 items-center justify-center rounded-lg border border-red-300 px-3 text-xs font-semibold text-red-700 transition hover:bg-red-50"
              >
                Remove Image
              </button>
            </div>
          ) : null}
        </div>
      ) : (
        <div className="mt-3 flex h-28 items-center justify-center rounded-lg border border-dashed border-primary/30 bg-primary-soft/50 text-xs font-semibold text-navy-muted">
          No image uploaded yet
        </div>
      )}
      {status ? <p className="mt-2 text-xs font-semibold text-navy-muted">{status}</p> : null}
    </div>
  );
}
