"use client";

import { useRef, useState } from "react";
import Cropper, { type Area } from "react-easy-crop";
import { cropImageToBlob } from "@/lib/image";
import { IconClose } from "@/components/icons";
import { AgoraLogo } from "@/components/agora-logo";

export function AvatarPicker({
  hasExistingPhoto = false,
  onCropped,
  onClear,
}: {
  hasExistingPhoto?: boolean;
  onCropped: (blob: Blob) => void;
  onClear?: () => void;
}) {
  const inputRef = useRef<HTMLInputElement>(null);
  const [rawImageSrc, setRawImageSrc] = useState<string | null>(null);
  const [pendingFileName, setPendingFileName] = useState<string | null>(null);
  const [fileName, setFileName] = useState<string | null>(null);
  const [crop, setCrop] = useState({ x: 0, y: 0 });
  const [zoom, setZoom] = useState(1);
  const [croppedAreaPixels, setCroppedAreaPixels] = useState<Area | null>(null);
  const [error, setError] = useState<string | null>(null);

  function handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
    const file = event.target.files?.[0];
    event.target.value = "";
    if (!file) return;

    const reader = new FileReader();
    reader.onload = () => {
      setRawImageSrc(reader.result as string);
      setPendingFileName(file.name);
      setCrop({ x: 0, y: 0 });
      setZoom(1);
      setError(null);
    };
    reader.readAsDataURL(file);
  }

  async function handleValidate() {
    if (!rawImageSrc || !croppedAreaPixels) return;
    try {
      const blob = await cropImageToBlob(rawImageSrc, croppedAreaPixels);
      onCropped(blob);
      setFileName(pendingFileName);
      setRawImageSrc(null);
      setPendingFileName(null);
    } catch {
      setError("Impossible de traiter cette image, réessaie.");
    }
  }

  function handleClearSelection() {
    setFileName(null);
    onClear?.();
  }

  function truncate(name: string): string {
    return name.length > 28 ? `${name.slice(0, 12)}…${name.slice(-10)}` : name;
  }

  if (rawImageSrc) {
    return (
      <div className="flex flex-col items-center gap-3">
        <div className="relative h-64 w-64 max-w-full overflow-hidden rounded-md bg-ink-2/10">
          <Cropper
            image={rawImageSrc}
            crop={crop}
            zoom={zoom}
            aspect={1}
            cropShape="round"
            showGrid={false}
            onCropChange={setCrop}
            onZoomChange={setZoom}
            onCropComplete={(_, pixels) => setCroppedAreaPixels(pixels)}
          />
        </div>
        <input
          type="range"
          min={1}
          max={3}
          step={0.05}
          value={zoom}
          onChange={(event) => setZoom(Number(event.target.value))}
          className="w-48"
          aria-label="Zoom"
        />
        <div className="flex gap-2">
          <button
            type="button"
            onClick={() => {
              setRawImageSrc(null);
              setPendingFileName(null);
            }}
            className="rounded-md border border-gold/40 px-3 py-1.5 text-sm text-text-marble hover:bg-gold/10"
          >
            Annuler
          </button>
          <button
            type="button"
            onClick={handleValidate}
            className="rounded-md bg-ink-2 px-3 py-1.5 text-sm font-medium text-gold-bright hover:bg-ink"
          >
            Valider le cadrage
          </button>
        </div>
        {error && <p className="text-xs text-oxblood">{error}</p>}
      </div>
    );
  }

  return (
    <div className="flex flex-col items-center gap-2">
      <input
        ref={inputRef}
        type="file"
        accept="image/*"
        onChange={handleFileChange}
        className="sr-only"
        aria-label="Choisir un fichier image"
      />
      <button
        type="button"
        onClick={() => inputRef.current?.click()}
        className="flex items-center gap-2 rounded-md bg-ink-2 px-3 py-1.5 text-sm font-medium text-gold-bright hover:bg-ink"
      >
        <AgoraLogo className="h-4 w-4" />
        {fileName || hasExistingPhoto ? "Changer ma photo" : "Choisir une photo"}
      </button>

      {fileName ? (
        <div className="flex items-center gap-1.5 text-xs text-text-mut">
          <span>{truncate(fileName)}</span>
          <button
            type="button"
            onClick={handleClearSelection}
            aria-label="Retirer la photo sélectionnée"
            className="rounded-full p-0.5 text-text-mut hover:bg-oxblood/10 hover:text-oxblood"
          >
            <IconClose className="h-3.5 w-3.5" />
          </button>
        </div>
      ) : (
        <span className="text-xs text-text-mut">Aucune photo sélectionnée</span>
      )}

      {error && <p className="text-xs text-oxblood">{error}</p>}
    </div>
  );
}
