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 TrashedContact = Tables<'contacts'> & {
  tags: Tables<'tags'>[];
};

export function useTrashedContacts() {
  const queryClient = useQueryClient();
  const { user } = useAuth();

  const trashedQuery = useQuery({
    queryKey: ['trashed-contacts'],
    queryFn: async () => {
      const { data: contacts, error } = await supabase
        .from('contacts')
        .select('*')
        .not('deleted_at', 'is', null)
        .order('deleted_at', { ascending: false });

      if (error) throw error;

      // Fetch tags for all contacts
      const { data: contactTags, error: tagsError } = await supabase
        .from('contact_tags')
        .select('contact_id, tag_id, tags(*)');

      if (tagsError) throw tagsError;

      // Map tags to contacts
      const contactsWithTags: TrashedContact[] = contacts.map((contact) => ({
        ...contact,
        tags: contactTags
          .filter((ct) => ct.contact_id === contact.id)
          .map((ct) => ct.tags)
          .filter(Boolean) as Tables<'tags'>[],
      }));

      return contactsWithTags;
    },
  });

  const restoreMutation = useMutation({
    mutationFn: async (contactId: string) => {
      const { error } = await supabase
        .from('contacts')
        .update({
          deleted_at: null,
          deleted_by: null,
          deleted_from: null,
        })
        .eq('id', contactId);

      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['trashed-contacts'] });
      queryClient.invalidateQueries({ queryKey: ['contacts'] });
      toast.success('Contact restored successfully');
    },
    onError: (error) => {
      toast.error('Failed to restore contact: ' + error.message);
    },
  });

  const permanentDeleteMutation = useMutation({
    mutationFn: async (contactId: string) => {
      // First, get all attachments for this contact
      const { data: attachments } = await supabase
        .from('attachments')
        .select('file_path')
        .eq('contact_id', contactId);

      // Delete files from storage
      if (attachments && attachments.length > 0) {
        const filePaths = attachments.map((a) => a.file_path);
        await supabase.storage.from('attachments').remove(filePaths);
      }

      // Get contact avatar
      const { data: contact } = await supabase
        .from('contacts')
        .select('avatar_url')
        .eq('id', contactId)
        .single();

      // Delete avatar from storage if exists
      if (contact?.avatar_url) {
        const avatarPath = contact.avatar_url.split('/').pop();
        if (avatarPath) {
          await supabase.storage.from('avatars').remove([avatarPath]);
        }
      }

      // Delete contact (cascades to attachments, tags, etc.)
      const { error } = await supabase
        .from('contacts')
        .delete()
        .eq('id', contactId);

      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['trashed-contacts'] });
      toast.success('Contact permanently deleted');
    },
    onError: (error) => {
      toast.error('Failed to delete contact: ' + error.message);
    },
  });

  const emptyTrashMutation = useMutation({
    mutationFn: async () => {
      // Get all trashed contacts
      const { data: trashedContacts } = await supabase
        .from('contacts')
        .select('id, avatar_url')
        .not('deleted_at', 'is', null);

      if (!trashedContacts || trashedContacts.length === 0) return;

      // Get all attachments for trashed contacts
      const contactIds = trashedContacts.map((c) => c.id);
      const { data: attachments } = await supabase
        .from('attachments')
        .select('file_path')
        .in('contact_id', contactIds);

      // Delete attachment files from storage
      if (attachments && attachments.length > 0) {
        const filePaths = attachments.map((a) => a.file_path);
        await supabase.storage.from('attachments').remove(filePaths);
      }

      // Delete avatar files from storage
      const avatarPaths = trashedContacts
        .filter((c) => c.avatar_url)
        .map((c) => c.avatar_url!.split('/').pop()!)
        .filter(Boolean);

      if (avatarPaths.length > 0) {
        await supabase.storage.from('avatars').remove(avatarPaths);
      }

      // Delete all trashed contacts
      const { error } = await supabase
        .from('contacts')
        .delete()
        .not('deleted_at', 'is', null);

      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['trashed-contacts'] });
      toast.success('Trash emptied successfully');
    },
    onError: (error) => {
      toast.error('Failed to empty trash: ' + error.message);
    },
  });

  const softDeleteMutation = useMutation({
    mutationFn: async ({ contactId, deletedFrom }: { contactId: string; deletedFrom: string }) => {
      const { error } = await supabase
        .from('contacts')
        .update({
          deleted_at: new Date().toISOString(),
          deleted_by: user?.id,
          deleted_from: deletedFrom,
        })
        .eq('id', contactId);

      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contacts'] });
      queryClient.invalidateQueries({ queryKey: ['trashed-contacts'] });
      toast.success('Contact moved to trash');
    },
    onError: (error) => {
      toast.error('Failed to delete contact: ' + error.message);
    },
  });

  return {
    trashedContacts: trashedQuery.data ?? [],
    isLoading: trashedQuery.isLoading,
    restore: restoreMutation.mutateAsync,
    permanentDelete: permanentDeleteMutation.mutateAsync,
    emptyTrash: emptyTrashMutation.mutateAsync,
    softDelete: softDeleteMutation.mutateAsync,
    isRestoring: restoreMutation.isPending,
    isDeleting: permanentDeleteMutation.isPending,
    isEmptyingTrash: emptyTrashMutation.isPending,
    isSoftDeleting: softDeleteMutation.isPending,
  };
}
