'use client';
import { useFileUpload } from '@/lib/hooks';
import { useAuth } from '@/lib/hooks/context';
import { useSupabaseClient } from '@/utils/supabase';
import {
  BasedAvatar,
  Card,
  CardContent,
} from '@/components/ui';
import { Loader2, Pencil, Upload } from 'lucide-react';
import type { ComponentProps, ChangeEvent } from 'react';
import { toast } from 'sonner';
import { cn } from '@/lib/utils';

type AvatarUploadProps = {
  onAvatarUploaded: (path: string) => Promise<void>;
  cardProps?: ComponentProps<typeof Card>;
  cardContentProps?: ComponentProps<typeof CardContent>;
  containerProps?: ComponentProps<'div'>;
  basedAvatarProps?: ComponentProps<typeof BasedAvatar>;
  iconProps?: ComponentProps<typeof Upload>;
};

export const AvatarUpload = ({
  onAvatarUploaded,
  cardProps,
  cardContentProps,
  containerProps,
  basedAvatarProps,
  iconProps = {
    size: 32,
  },
}: AvatarUploadProps) => {
  const { profile, isAuthenticated } = useAuth();
  const { isUploading, fileInputRef, uploadAvatarMutation } = useFileUpload();
  const client = useSupabaseClient();

  const handleAvatarClick = () => {
    if (!isAuthenticated) {
      toast.error('You must be logged in to upload an avatar!');
      return;
    }
    fileInputRef.current?.click();
  };

  const handleFileChange = async (e: ChangeEvent<HTMLInputElement>) => {
    try {
      const file = e.target.files?.[0];
      if (!file) throw new Error('No file selected!');
      if (!client) throw new Error('Supabase client not found!');
      if (!isAuthenticated) throw new Error('User is not authenticated!');
      if (!file.type.startsWith('image/')) throw new Error('File is not an image!');
      if (file.size > 8 * 1024 * 1024) throw new Error('File is too large!');

      const avatarPath = profile?.avatar_url ??
        `${profile?.id}.${file.name.split('.').pop()}`;

      const avatarUrl = await uploadAvatarMutation.mutateAsync({
        client,
        file,
        bucket: 'avatars',
        resize: {
          maxWidth: 500,
          maxHeight: 500,
          quality: 0.8,
        },
        replace: avatarPath,
      });
      if (avatarUrl) await onAvatarUploaded(avatarUrl);

    } catch (error) {
      toast.error(`Error: ${error as string}`);
    }
  };

  return (
    <Card
      {...cardProps}
      className={cn('', cardProps?.className)}
    >
      <CardContent
        {...cardContentProps}
        className={cn('flex flex-col items-center', cardContentProps?.className)}
      >
        <div
          {...containerProps}
          className={cn(
            'relative group cursor-pointer mb-4',
            containerProps?.className
          )}
        >
          <BasedAvatar
            {...basedAvatarProps}
            src={profile?.avatar_url}
            fullName={profile?.full_name}
            className={cn('h-32, w-32', basedAvatarProps?.className)}
            fallbackProps={{ className: 'text-4xl font-semibold' }}
            userIconProps={{ size: 100 }}
          />
          <div
            className={cn(
              'absoloute inset-0 rounded-full bg-black/0\
              group-hover:bg-black/50 transition-all flex\
              items-center justify-center'
            )}
          >
            <Upload
              {...iconProps}
              className={cn('text-white opacity-0 group-hover:opacity-100\
                transition-opacity', iconProps?.className
              )}
            />
          </div>
          <div
            className={cn(
              'absolute inset-1 transition-all flex\
                items-end justify-end',
            )}
          >
            <Pencil
              {...iconProps}
              className={cn(
                'text-white opacity-100 group-hover:opacity-0\
                  transition-opacity', iconProps?.className
              )}
            />
          </div>
          <input
            ref={fileInputRef}
            type='file'
            accept='image/*'
            className={cn('hidden')}
            onChange={handleFileChange}
            disabled={isUploading}
          />
          {isUploading && (
            <div className={cn('flex items-center text-sm text-gray-500 mt-2')}>
              <Loader2 className={cn('h-4 w-4 mr-2 animate-spin')} />
              Uploading...
            </div>
          )}
          {!isAuthenticated && (
            <p className={cn('text-sm text-muted-foreground mt-2')}>
              Sign in to upload an avatar.
            </p>
          )}
        </div>
      </CardContent>
    </Card>
  );
};
