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

export type Tenancy = Tables<'tenancies'>;
export type TenancyInsert = TablesInsert<'tenancies'>;
export type TenancyUpdate = TablesUpdate<'tenancies'>;

export interface TenancyWithRelations extends Tenancy {
  tenant?: {
    id: string;
    first_name: string;
    last_name: string;
    email: string;
    phone: string | null;
    company: string | null;
  } | null;
  property?: {
    id: string;
    reference: string | null;
    display_address: string | null;
    address_line_1: string | null;
    town_city: string | null;
    postcode: string | null;
    landlord_id: string | null;
  } | null;
}

export const useTenancies = () => {
  return useQuery({
    queryKey: ['tenancies'],
    queryFn: async () => {
      const { data, error } = await supabase
        .from('tenancies')
        .select(`
          *,
          tenant:contacts!tenancies_tenant_id_fkey(id, first_name, last_name, email, phone, company),
          property:properties!tenancies_property_id_fkey(id, reference, display_address, address_line_1, town_city, postcode, landlord_id)
        `)
        .is('deleted_at', null)
        .order('created_at', { ascending: false });

      if (error) throw error;
      return data as TenancyWithRelations[];
    },
  });
};

export const useTenancy = (id: string | undefined) => {
  return useQuery({
    queryKey: ['tenancy', id],
    queryFn: async () => {
      if (!id) return null;
      
      const { data, error } = await supabase
        .from('tenancies')
        .select(`
          *,
          tenant:contacts!tenancies_tenant_id_fkey(id, first_name, last_name, email, phone, company),
          property:properties!tenancies_property_id_fkey(
            id, reference, display_address, address_line_1, address_line_2, 
            town_city, county, postcode, country, landlord_id,
            landlord:contacts!properties_landlord_id_fkey(id, first_name, last_name, email, phone, company)
          )
        `)
        .eq('id', id)
        .single();

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

export const useTenantContacts = () => {
  return useQuery({
    queryKey: ['tenant-contacts'],
    queryFn: async () => {
      // First get the Tenant tag
      const { data: tenantTag, error: tagError } = await supabase
        .from('tags')
        .select('id')
        .ilike('name', 'tenant')
        .single();

      if (tagError || !tenantTag) {
        return { contacts: [], hasTenantTag: false };
      }

      // Get contacts with this tag
      const { data: contactTags, error: contactTagsError } = await supabase
        .from('contact_tags')
        .select('contact_id')
        .eq('tag_id', tenantTag.id);

      if (contactTagsError) throw contactTagsError;

      if (!contactTags || contactTags.length === 0) {
        return { contacts: [], hasTenantTag: true };
      }

      const contactIds = contactTags.map(ct => ct.contact_id);

      const { data: contacts, error: contactsError } = await supabase
        .from('contacts')
        .select('id, first_name, last_name, email, phone, company')
        .in('id', contactIds)
        .is('deleted_at', null);

      if (contactsError) throw contactsError;

      return { contacts: contacts || [], hasTenantTag: true };
    },
  });
};

export const useProperties = () => {
  return useQuery({
    queryKey: ['properties-for-tenancy'],
    queryFn: async () => {
      const { data, error } = await supabase
        .from('properties')
        .select('id, reference, display_address, address_line_1, town_city, postcode, landlord_id')
        .is('deleted_at', null)
        .order('created_at', { ascending: false });

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

export const useCreateTenancy = () => {
  const queryClient = useQueryClient();
  const { user } = useAuth();

  return useMutation({
    mutationFn: async (tenancy: TenancyInsert) => {
      // If this tenancy is active and has a property_id, end any existing active tenancies
      if (tenancy.status === 'active' && tenancy.property_id) {
        const { data: existingActive } = await supabase
          .from('tenancies')
          .select('id, reference')
          .eq('property_id', tenancy.property_id)
          .eq('status', 'active')
          .is('deleted_at', null);

        if (existingActive && existingActive.length > 0) {
          // End all existing active tenancies for this property
          const { error: updateError } = await supabase
            .from('tenancies')
            .update({ status: 'ended' })
            .in('id', existingActive.map(t => t.id));

          if (updateError) throw updateError;

          // Log the status change
          if (user) {
            for (const t of existingActive) {
              await supabase.from('activities').insert({
                type: 'system',
                direction: 'log',
                subject: 'Tenancy Ended',
                body_preview: `Tenancy ${t.reference || t.id} ended - new active tenancy created`,
                user_id: user.id,
                category: 'tenancy',
              });
            }
          }
        }
      }

      const { data, error } = await supabase
        .from('tenancies')
        .insert(tenancy)
        .select()
        .single();

      if (error) throw error;

      // Log activity
      if (user) {
        await supabase.from('activities').insert({
          type: 'system',
          direction: 'log',
          subject: 'Tenancy Created',
          body_preview: `New tenancy ${tenancy.reference || 'created'}`,
          user_id: user.id,
          category: 'tenancy',
        });
      }

      return data;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tenancies'] });
      queryClient.invalidateQueries({ queryKey: ['property-tenancies'] });
      toast.success('Tenancy created successfully');
    },
    onError: (error) => {
      toast.error('Failed to create tenancy: ' + error.message);
    },
  });
};

export const useUpdateTenancy = () => {
  const queryClient = useQueryClient();
  const { user } = useAuth();

  return useMutation({
    mutationFn: async ({ id, ...updates }: TenancyUpdate & { id: string }) => {
      // If updating to active status and has a property_id, end any other active tenancies
      if (updates.status === 'active' && updates.property_id) {
        const { data: existingActive } = await supabase
          .from('tenancies')
          .select('id, reference')
          .eq('property_id', updates.property_id)
          .eq('status', 'active')
          .neq('id', id)
          .is('deleted_at', null);

        if (existingActive && existingActive.length > 0) {
          // End all other active tenancies for this property
          const { error: updateError } = await supabase
            .from('tenancies')
            .update({ status: 'ended' })
            .in('id', existingActive.map(t => t.id));

          if (updateError) throw updateError;

          // Log the status change
          if (user) {
            for (const t of existingActive) {
              await supabase.from('activities').insert({
                type: 'system',
                direction: 'log',
                subject: 'Tenancy Ended',
                body_preview: `Tenancy ${t.reference || t.id} ended - another tenancy set to active`,
                user_id: user.id,
                category: 'tenancy',
              });
            }
          }
        }
      }

      const { data, error } = await supabase
        .from('tenancies')
        .update(updates)
        .eq('id', id)
        .select()
        .single();

      if (error) throw error;

      // Log activity
      if (user) {
        await supabase.from('activities').insert({
          type: 'system',
          direction: 'log',
          subject: 'Tenancy Updated',
          body_preview: `Tenancy ${data.reference || id} was updated`,
          user_id: user.id,
          category: 'tenancy',
        });
      }

      return data;
    },
    onSuccess: (data) => {
      queryClient.invalidateQueries({ queryKey: ['tenancies'] });
      queryClient.invalidateQueries({ queryKey: ['tenancy', data.id] });
      queryClient.invalidateQueries({ queryKey: ['property-tenancies'] });
      toast.success('Tenancy updated successfully');
    },
    onError: (error) => {
      toast.error('Failed to update tenancy: ' + error.message);
    },
  });
};

export const useDeleteTenancy = () => {
  const queryClient = useQueryClient();
  const { user } = useAuth();

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

      if (error) throw error;

      // Log activity
      if (user) {
        await supabase.from('activities').insert({
          type: 'system',
          direction: 'log',
          subject: 'Tenancy Deleted',
          body_preview: `Tenancy was deleted`,
          user_id: user.id,
          category: 'tenancy',
        });
      }

      return id;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: ['tenancies'] });
      toast.success('Tenancy deleted successfully');
    },
    onError: (error) => {
      toast.error('Failed to delete tenancy: ' + error.message);
    },
  });
};
