import { ImageIcon, User, X } from "lucide-react";
import { useCallback, useEffect, useState } from "react";
import z from "zod/v3";
import { Avatar, AvatarFallback, AvatarImage } from "~/components/ui/avatar";
import { Button } from "~/components/ui/button";
import { validateFile } from "~/features/file";

// Avatar Upload Component with Drag & Drop
export interface AvatarUploadProps {
  value?: File | string | null;
  onChange: (file: File | null) => void;
  error?: string;
}

export function AvatarUpload({ value, onChange, error }: AvatarUploadProps) {
  const [preview, setPreview] = useState<string | null>(null);
  const [isDragging, setIsDragging] = useState(false);

  const handleFileChange = useCallback(
    (file: File | null) => {
      if (file) {
        const validationError = validateFile(file);
        if (validationError) {
          onChange(file);
          return;
        }

        const reader = new FileReader();
        reader.onload = (e) => {
          setPreview(e.target?.result as string);
        };
        reader.readAsDataURL(file);
        onChange(file);
      } else {
        setPreview(null);
        onChange(null);
      }
    },
    [onChange]
  );

  const handleDrop = useCallback(
    (e: React.DragEvent) => {
      e.preventDefault();
      setIsDragging(false);

      const files = Array.from(e.dataTransfer.files);
      if (files.length > 0) {
        handleFileChange(files[0]);
      }
    },
    [handleFileChange]
  );

  const handleDragOver = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(true);
  }, []);

  const handleDragLeave = useCallback((e: React.DragEvent) => {
    e.preventDefault();
    setIsDragging(false);
  }, []);

  const handleInputChange = useCallback(
    (e: React.ChangeEvent<HTMLInputElement>) => {
      const file = e.target.files?.[0] || null;
      handleFileChange(file);
    },
    [handleFileChange]
  );

  const removeFile = useCallback(() => {
    handleFileChange(null);
  }, [handleFileChange]);

  useEffect(() => {
    if (z.string().url().safeParse(value).success) {
      setPreview(value as string);
    }
  }, [value]);

  return (
    <div className="space-y-4">
      <div className="flex items-center gap-4">
        <Avatar className="h-20 w-20">
          <AvatarImage src={preview || undefined} />
          <AvatarFallback>
            <User className="h-8 w-8" />
          </AvatarFallback>
        </Avatar>

        <div
          className={`flex-1 border-2 border-dashed rounded-lg p-4 text-center cursor-pointer transition-colors ${
            isDragging
              ? "border-primary bg-primary/5"
              : error
              ? "border-red-500"
              : "border-gray-300 hover:border-primary"
          }`}
          onDrop={handleDrop}
          onDragOver={handleDragOver}
          onDragLeave={handleDragLeave}
          onClick={() => document.getElementById("avatar-input")?.click()}
        >
          <input
            id="avatar-input"
            type="file"
            accept="image/*"
            className="hidden"
            onChange={handleInputChange}
          />

          <div className="flex flex-col items-center gap-2">
            <ImageIcon className="h-8 w-8 text-gray-400" />
            <div className="text-sm">
              <span className="font-medium text-primary">Nhấp để tải lên</span>{" "}
              hoặc kéo thả ảnh vào đây
            </div>
            <div className="text-xs text-gray-500">
              PNG, JPG, GIF, WebP (tối đa 2MB)
            </div>
          </div>
        </div>

        {preview && (
          <Button
            type="button"
            variant="outline"
            size="sm"
            onClick={removeFile}
          >
            <X className="h-4 w-4" />
          </Button>
        )}
      </div>
    </div>
  );
}
