import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { supabase } from '@/integrations/supabase/client';
import { Tables } from '@/integrations/supabase/types';
import { toast } from 'sonner';
import { useAuth } from '@/contexts/AuthContext';

export type Attachment = Tables<'attachments'>;

export const ATTACHMENT_CATEGORIES = [
  'general',
  'contract',
  'invoice',
  'proposal',
  'report',
  'image',
  'other',
] as const;

export type AttachmentCategory = typeof ATTACHMENT_CATEGORIES[number];

export function useAttachments(contactId: string) {
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const attachmentsQuery = useQuery({
    queryKey: ['attachments', contactId],
    queryFn: async () => {
      const { data, error } = await supabase
        .from('attachments')
        .select('*')
        .eq('contact_id', contactId)
        .order('created_at', { ascending: false });

      if (error) throw error;
      return data;
    },
    enabled: !!contactId,
  });

  const uploadMutation = useMutation({
    mutationFn: async ({ file, category }: { file: File; category: AttachmentCategory }) => {
      if (!user) throw new Error('User not authenticated');

      // Generate unique file path
      const fileExt = file.name.split('.').pop();
      const fileName = `${contactId}/${Date.now()}-${Math.random().toString(36).substring(7)}.${fileExt}`;

      // Upload file to storage
      const { error: uploadError } = await supabase.storage
        .from('attachments')
        .upload(fileName, file);

      if (uploadError) throw uploadError;

      // Create attachment record
      const { data, error } = await supabase
        .from('attachments')
        .insert({
          contact_id: contactId,
          file_name: file.name,
          file_path: fileName,
          file_size: file.size,
          mime_type: file.type,
          category,
          uploaded_by: user.id,
        })
        .select()
        .single();

      if (error) {
        // Clean up uploaded file if record creation fails
        await supabase.storage.from('attachments').remove([fileName]);
        throw error;
      }

      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['attachments', contactId] });
      toast.success('File uploaded successfully');
    },
    onError: (error) => {
      toast.error('Failed to upload file: ' + error.message);
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async (attachmentId: string) => {
      // Get attachment details first
      const { data: attachment, error: fetchError } = await supabase
        .from('attachments')
        .select('file_path')
        .eq('id', attachmentId)
        .single();

      if (fetchError) throw fetchError;

      // Delete file from storage
      const { error: storageError } = await supabase.storage
        .from('attachments')
        .remove([attachment.file_path]);

      if (storageError) throw storageError;

      // Delete attachment record
      const { error } = await supabase
        .from('attachments')
        .delete()
        .eq('id', attachmentId);

      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['attachments', contactId] });
      toast.success('Attachment deleted');
    },
    onError: (error) => {
      toast.error('Failed to delete attachment: ' + error.message);
    },
  });

  const getDownloadUrl = async (filePath: string): Promise<string> => {
    const { data, error } = await supabase.storage
      .from('attachments')
      .createSignedUrl(filePath, 3600); // 1 hour expiry

    if (error) throw error;
    return data.signedUrl;
  };

  return {
    attachments: attachmentsQuery.data ?? [],
    isLoading: attachmentsQuery.isLoading,
    upload: uploadMutation.mutateAsync,
    deleteAttachment: deleteMutation.mutateAsync,
    getDownloadUrl,
    isUploading: uploadMutation.isPending,
    isDeleting: deleteMutation.isPending,
  };
}
