import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { supabase } from '@/integrations/supabase/client';
import { Tables, TablesInsert, TablesUpdate } from '@/integrations/supabase/types';
import { toast } from 'sonner';
import { useAuth } from '@/contexts/AuthContext';
import { logStatusChange, logPipelineChange, logContactUpdate, logSystemActivity } from '@/lib/activityLogger';

export type Contact = Tables<'contacts'>;
export type ContactInsert = TablesInsert<'contacts'>;
export type ContactUpdate = TablesUpdate<'contacts'>;

export interface ContactWithTags extends Contact {
  tags: Tables<'tags'>[];
}

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

  const contactsQuery = useQuery({
    queryKey: ['contacts'],
    queryFn: async () => {
      // Only fetch non-deleted contacts
      const { data: contacts, error } = await supabase
        .from('contacts')
        .select('*')
        .is('deleted_at', null)
        .order('created_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: ContactWithTags[] = 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 createMutation = useMutation({
    mutationFn: async (contact: ContactInsert) => {
      const { data, error } = await supabase
        .from('contacts')
        .insert(contact)
        .select()
        .single();

      if (error) throw error;
      return data;
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['contacts'] });
      toast.success('Contact created successfully');
      
      // Log activity
      if (user) {
        logSystemActivity(user.id, data.id, 'Contact created', `${data.first_name} ${data.last_name} was added`);
      }
    },
    onError: (error) => {
      toast.error('Failed to create contact: ' + error.message);
    },
  });

  const updateMutation = useMutation({
    mutationFn: async ({ id, previousData, ...updates }: ContactUpdate & { id: string; previousData?: Contact }) => {
      const { data, error } = await supabase
        .from('contacts')
        .update(updates)
        .eq('id', id)
        .select()
        .single();

      if (error) throw error;
      return { data, previousData };
    },
    onSuccess: ({ data, previousData }) => {
      queryClient.invalidateQueries({ queryKey: ['contacts'] });
      toast.success('Contact updated successfully');
      
      if (!user || !previousData) return;
      
      // Log status change
      if (previousData.status !== data.status) {
        logStatusChange(user.id, data.id, previousData.status, data.status);
      }
      
      // Log pipeline/stage change
      if (previousData.stage_id !== data.stage_id && data.stage_id) {
        // We'd need stage name here, but for simplicity log the change
        logPipelineChange(user.id, data.id, 'new stage');
      }
      
      // Log other field updates
      const changedFields: string[] = [];
      if (previousData.email !== data.email) changedFields.push('email');
      if (previousData.phone !== data.phone) changedFields.push('phone');
      if (previousData.company !== data.company) changedFields.push('company');
      if (previousData.first_name !== data.first_name) changedFields.push('first name');
      if (previousData.last_name !== data.last_name) changedFields.push('last name');
      
      if (changedFields.length > 0) {
        logContactUpdate(user.id, data.id, changedFields);
      }
    },
    onError: (error) => {
      toast.error('Failed to update contact: ' + error.message);
    },
  });

  const deleteMutation = useMutation({
    mutationFn: async (id: string) => {
      const { error } = await supabase.from('contacts').delete().eq('id', id);
      if (error) throw error;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['contacts'] });
      toast.success('Contact deleted successfully');
    },
    onError: (error) => {
      toast.error('Failed to delete contact: ' + error.message);
    },
  });

  return {
    contacts: contactsQuery.data ?? [],
    isLoading: contactsQuery.isLoading,
    error: contactsQuery.error,
    createContact: createMutation.mutateAsync,
    updateContact: updateMutation.mutateAsync,
    deleteContact: deleteMutation.mutateAsync,
    isCreating: createMutation.isPending,
    isUpdating: updateMutation.isPending,
    isDeleting: deleteMutation.isPending,
  };
}

export function useTags() {
  return useQuery({
    queryKey: ['tags'],
    queryFn: async () => {
      const { data, error } = await supabase
        .from('tags')
        .select('*')
        .order('name');

      if (error) throw error;
      return data;
    },
  });
}
