import { useRef, useState } from 'react';
import { toast } from 'sonner';
import { Camera } from 'lucide-react';
import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Button } from '@/components/ui/button';
import { useForm } from 'hooks/useForm';
import { useAuth } from 'hooks/useAuth';

type ProfileFormState = {
  name?: string;
};

const MAX_AVATAR_SIZE = 384_000; // ~384KB to stay under 512KB varchar after base64 overhead

const readFileAsBase64 = (file: File): Promise<string> => {
  return new Promise((resolve, reject) => {
    const reader = new FileReader();
    reader.onload = () => resolve(reader.result as string);
    reader.onerror = reject;
    reader.readAsDataURL(file);
  });
};

export const UserData = () => {
  const { user, updateUser } = useAuth();
  const [isUpdating, setIsUpdating] = useState(false);
  const [avatarPreview, setAvatarPreview] = useState<string | null>(null);
  const fileInputRef = useRef<HTMLInputElement | null>(null);
  const profileForm = useForm<ProfileFormState>({ name: user?.name ?? '' });

  const handleAvatarChange = async (ev: React.ChangeEvent<HTMLInputElement>) => {
    const file = ev.target.files?.[0];
    if (!file) return;

    if (!file.type.startsWith('image/')) {
      toast.error('Please select an image file');
      return;
    }

    if (file.size > MAX_AVATAR_SIZE) {
      toast.error('Image must be smaller than 384KB');
      return;
    }

    const base64 = await readFileAsBase64(file);
    setAvatarPreview(base64);
  };

  const handleSubmit = async (ev: React.FormEvent) => {
    ev.preventDefault();
    if (isUpdating) return;

    setIsUpdating(true);
    try {
      await updateUser({
        name: profileForm.state.name ?? '',
        avatar: avatarPreview ?? user?.avatar ?? '',
      });
      toast.success('Profile updated');
      setAvatarPreview(null);
    } catch (ex) {
      const error = ex as { message?: string };
      toast.error(error.message || 'Failed to update profile');
    } finally {
      setIsUpdating(false);
    }
  };

  const displayAvatar = avatarPreview ?? user?.avatar ?? undefined;

  return (
    <div>
      <div className="flex justify-center mb-6">
        <button
          type="button"
          className="relative group cursor-pointer rounded-full"
          onClick={() => fileInputRef.current?.click()}
        >
          <Avatar className="h-20 w-20 rounded-full">
            <AvatarImage src={displayAvatar} />
            <AvatarFallback className="bg-duck-teal text-duck-yellow text-2xl font-bold rounded-full">
              {user?.name?.charAt(0).toUpperCase() ?? '?'}
            </AvatarFallback>
          </Avatar>
          <div className="absolute inset-0 rounded-full bg-black/40 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-center">
            <Camera className="h-6 w-6 text-white" />
          </div>
        </button>
        <input ref={fileInputRef} type="file" accept="image/*" className="hidden" onChange={handleAvatarChange} />
      </div>

      <form ref={profileForm.formRef} onSubmit={handleSubmit} className="grid gap-4">
        <Label className="grid gap-2">
          <span className="text-duck-dark/70">Email</span>
          <Input
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark placeholder:text-duck-dark/40"
            type="email"
            value={user?.email ?? ''}
            disabled
          />
        </Label>

        <Label className="grid gap-2">
          <span className="text-duck-dark/70">Username</span>
          <Input
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark placeholder:text-duck-dark/40"
            type="text"
            value={user?.username ?? ''}
            disabled
          />
        </Label>

        <Label className="grid gap-2">
          <span className="text-duck-dark/70">Name</span>
          <Input
            className="h-11 bg-background/60 border-duck-dark/20 text-duck-dark placeholder:text-duck-dark/40"
            type="text"
            name="name"
            placeholder="Your name"
            autoComplete="name"
          />
        </Label>

        <Button
          type="submit"
          disabled={isUpdating}
          className="w-full h-11 bg-duck-yellow hover:bg-duck-yellow/90 text-duck-teal font-bold transition-all duration-200 hover:scale-105 cursor-pointer disabled:opacity-50 disabled:hover:scale-100"
        >
          {isUpdating ? 'Saving...' : 'Save'}
        </Button>
      </form>
    </div>
  );
};
