import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { supabase } from '@/lib/supabaseClient';
import { queryKeys } from '@/lib/queryKeys';
import { toast } from 'sonner';

export interface Incident {
  id: string;
  incident_number: string;
  title: string;
  description: string;
  severity: 'critical' | 'high' | 'medium' | 'low';
  status: 'open' | 'investigating' | 'resolved' | 'closed';
  correlation_rule_id?: string;
  detected_at: string;
  acknowledged_at?: string;
  acknowledged_by?: string;
  resolved_at?: string;
  resolved_by?: string;
  resolution_notes?: string;
  alert_count: number;
  created_at: string;
  updated_at: string;
}

export function useIncidents(status?: 'open' | 'investigating' | 'resolved' | 'closed') {
  return useQuery({
    queryKey: queryKeys.monitoring.incidents(status),
    queryFn: async () => {
      let query = supabase
        .from('incidents')
        .select('*')
        .order('detected_at', { ascending: false });

      if (status) {
        query = query.eq('status', status);
      }

      const { data, error } = await query;
      if (error) throw error;
      return (data || []) as Incident[];
    },
    staleTime: 15000,
    refetchInterval: 30000,
  });
}

export function useCreateIncident() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({
      ruleId,
      title,
      description,
      severity,
      alertIds,
      alertSources,
    }: {
      ruleId?: string;
      title: string;
      description?: string;
      severity: 'critical' | 'high' | 'medium' | 'low';
      alertIds: string[];
      alertSources: ('system' | 'rate_limit')[];
    }) => {
      // Create the incident (incident_number is auto-generated by trigger)
      const { data: incident, error: incidentError } = await supabase
        .from('incidents')
        .insert([{
          title,
          description,
          severity,
          correlation_rule_id: ruleId,
          status: 'open' as const,
        } as any])
        .select()
        .single();

      if (incidentError) throw incidentError;

      // Link alerts to the incident
      const incidentAlerts = alertIds.map((alertId, index) => ({
        incident_id: incident.id,
        alert_source: alertSources[index] || 'system',
        alert_id: alertId,
      }));

      const { error: linkError } = await supabase
        .from('incident_alerts')
        .insert(incidentAlerts);

      if (linkError) throw linkError;
      
      // Log to audit trail
      const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
      await logAdminAction('incident_created', {
        incident_id: incident.id,
        incident_number: incident.incident_number,
        title: title,
        severity: severity,
        alert_count: alertIds.length,
        correlation_rule_id: ruleId,
      });

      return incident as Incident;
    },
    onSuccess: (incident) => {
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.incidents() });
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.correlatedAlerts() });
      toast.success(`Incident ${incident.incident_number} created`);
    },
    onError: (error) => {
      console.error('Failed to create incident:', error);
      toast.error('Failed to create incident');
    },
  });
}

export function useAcknowledgeIncident() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async (incidentId: string) => {
      const { data, error } = await supabase
        .from('incidents')
        .update({
          status: 'investigating',
          acknowledged_at: new Date().toISOString(),
          acknowledged_by: (await supabase.auth.getUser()).data.user?.id,
        })
        .eq('id', incidentId)
        .select()
        .single();

      if (error) throw error;
      
      // Log to audit trail
      const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
      await logAdminAction('incident_acknowledged', {
        incident_id: incidentId,
        incident_number: data.incident_number,
        severity: data.severity,
        status_change: 'open -> investigating',
      });
      
      return data as Incident;
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.incidents() });
      toast.success('Incident acknowledged');
    },
    onError: (error) => {
      console.error('Failed to acknowledge incident:', error);
      toast.error('Failed to acknowledge incident');
    },
  });
}

export function useResolveIncident() {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: async ({
      incidentId,
      resolutionNotes,
      resolveAlerts = true,
    }: {
      incidentId: string;
      resolutionNotes?: string;
      resolveAlerts?: boolean;
    }) => {
      const userId = (await supabase.auth.getUser()).data.user?.id;
      
      // Fetch incident details before resolving
      const { data: incident } = await supabase
        .from('incidents')
        .select('incident_number, severity, alert_count')
        .eq('id', incidentId)
        .single();

      // Update incident
      const { error: incidentError } = await supabase
        .from('incidents')
        .update({
          status: 'resolved',
          resolved_at: new Date().toISOString(),
          resolved_by: userId,
          resolution_notes: resolutionNotes,
        })
        .eq('id', incidentId);

      if (incidentError) throw incidentError;
      
      // Log to audit trail
      const { logAdminAction } = await import('@/lib/adminActionAuditHelpers');
      await logAdminAction('incident_resolved', {
        incident_id: incidentId,
        incident_number: incident?.incident_number,
        severity: incident?.severity,
        alert_count: incident?.alert_count,
        resolution_notes: resolutionNotes,
        resolved_linked_alerts: resolveAlerts,
      });

      // Optionally resolve all linked alerts
      if (resolveAlerts) {
        const { data: linkedAlerts } = await supabase
          .from('incident_alerts')
          .select('alert_source, alert_id')
          .eq('incident_id', incidentId);

        if (linkedAlerts) {
          for (const alert of linkedAlerts) {
            const table = alert.alert_source === 'system' ? 'system_alerts' : 'rate_limit_alerts';
            await supabase
              .from(table)
              .update({ resolved_at: new Date().toISOString() })
              .eq('id', alert.alert_id);
          }
        }
      }

      return { incidentId };
    },
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.incidents() });
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.groupedAlerts() });
      queryClient.invalidateQueries({ queryKey: queryKeys.monitoring.combinedAlerts() });
      toast.success('Incident resolved');
    },
    onError: (error) => {
      console.error('Failed to resolve incident:', error);
      toast.error('Failed to resolve incident');
    },
  });
}
