import { useMutation, useQuery, useQueryClient } from '@tanstack/react-query'
import { useEffect } from 'react'

import {
  ai_plan_chat_v2,
  ai_plan_improve,
  ai_subject_improve,
  create_conversation,
  get_chat_history,
  getConversationByPlan,
  library_search,
  update_conversation_status,
  update_recommendation_applied_status,
  update_conversation_title,
  getMessagesByConversation,
  update_subject_conversation_status,
  update_subject_recommendation_applied,
  getMessagesBySubjectConversation,
  getConversationBySubject,
  ai_subject_chat_v2,
  create_subject_conversation,
  update_subject_conversation_name,
} from '../api/ai.api'
import { supabaseBrowser } from '../supabase/client'

import type { UUID } from 'node:crypto'

export function useAIPlanImprove() {
  return useMutation({ mutationFn: ai_plan_improve })
}

export function useAIPlanChat() {
  return useMutation({
    mutationFn: async (payload: {
      planId: UUID
      content: string
      campos?: Array<string>
      conversacionId?: string
    }) => {
      let currentId = payload.conversacionId

      // 1. Si no hay ID, creamos la conversación
      if (!currentId) {
        const response = await create_conversation(payload.planId)

        // CAMBIO AQUÍ: Accedemos a la estructura correcta según tu consola
        currentId = response.conversation_plan.id
      }

      // 2. Ahora enviamos el mensaje con el ID garantizado
      const result = await ai_plan_chat_v2({
        conversacionId: currentId!,
        content: payload.content,
        campos: payload.campos,
      })

      // Retornamos el resultado del chat y el ID para el estado del componente
      return { ...result, conversacionId: currentId }
    },
  })
}

export function useChatHistory(conversacionId?: string) {
  return useQuery({
    queryKey: ['chat-history', conversacionId],
    queryFn: async () => {
      return get_chat_history(conversacionId!)
    },
    enabled: Boolean(conversacionId),
  })
}

export function useUpdateConversationStatus() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: ({
      id,
      estado,
    }: {
      id: string
      estado: 'ARCHIVADA' | 'ACTIVA'
    }) => update_conversation_status(id, estado),
    onSuccess: () => {
      // Esto refresca las listas automáticamente
      qc.invalidateQueries({ queryKey: ['conversation-by-plan'] })
    },
  })
}

export function useConversationByPlan(planId: string | null) {
  return useQuery({
    queryKey: ['conversation-by-plan', planId],
    queryFn: () => getConversationByPlan(planId!),
    enabled: !!planId, // solo ejecuta si existe planId
  })
}

export function useMessagesByChat(conversationId: string | null) {
  const queryClient = useQueryClient()
  const supabase = supabaseBrowser()

  const query = useQuery({
    queryKey: ['conversation-messages', conversationId],
    queryFn: () => {
      if (!conversationId) throw new Error('Conversation ID is required')
      return getMessagesByConversation(conversationId)
    },
    enabled: !!conversationId,
    placeholderData: (previousData) => previousData,
  })

  useEffect(() => {
    if (!conversationId) return

    // Suscribirse a cambios en los mensajes de ESTA conversación
    const channel = supabase
      .channel(`realtime-messages-${conversationId}`)
      .on(
        'postgres_changes',
        {
          event: '*', // Escuchamos INSERT y UPDATE
          schema: 'public',
          table: 'plan_mensajes_ia',
          filter: `conversacion_plan_id=eq.${conversationId}`,
        },
        (payload) => {
          // Opción A: Invalidar la query para que React Query haga refetch (más seguro)
          queryClient.invalidateQueries({
            queryKey: ['conversation-messages', conversationId],
          })

          /* Opción B: Actualización manual del caché (más rápido/fluido)
             if (payload.eventType === 'INSERT') {
               queryClient.setQueryData(['conversation-messages', conversationId], (old: any) => [...old, payload.new])
             } else if (payload.eventType === 'UPDATE') {
               queryClient.setQueryData(['conversation-messages', conversationId], (old: any) => 
                 old.map((m: any) => m.id === payload.new.id ? payload.new : m)
               )
             }
          */
        },
      )
      .subscribe()

    return () => {
      supabase.removeChannel(channel)
    }
  }, [conversationId, queryClient, supabase])

  return query
}

export function useUpdateRecommendationApplied() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: ({
      conversacionId,
      campoAfectado,
    }: {
      conversacionId: string
      campoAfectado: string
    }) => update_recommendation_applied_status(conversacionId, campoAfectado),

    onSuccess: (_, variables) => {
      // Invalidamos la query para que useConversationByPlan refresque el JSON
      qc.invalidateQueries({ queryKey: ['conversation-by-plan'] })
      console.log(
        `Recomendación ${variables.campoAfectado} marcada como aplicada.`,
      )
    },
    onError: (error) => {
      console.error('Error al actualizar el estado de la recomendación:', error)
    },
  })
}

export function useAISubjectImprove() {
  return useMutation({ mutationFn: ai_subject_improve })
}

export function useLibrarySearch() {
  return useMutation({ mutationFn: library_search })
}

export function useUpdateConversationTitle() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: ({ id, nombre }: { id: string; nombre: string }) =>
      update_conversation_title(id, nombre),
    onSuccess: (_, variables) => {
      // Invalidamos para que la lista de chats se refresque
      qc.invalidateQueries({ queryKey: ['conversation-by-plan'] })
    },
  })
}

// Asignaturas

export function useAISubjectChat() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: async (payload: {
      subjectId: UUID
      content: string
      campos?: Array<string>
      conversacionId?: string
    }) => {
      let currentId = payload.conversacionId

      // 1. Si no hay ID, creamos la conversación de asignatura
      if (!currentId) {
        const response = await create_subject_conversation(payload.subjectId)
        currentId = response.conversation_asignatura.id
      }

      // 2. Enviamos mensaje al endpoint de asignatura
      const result = await ai_subject_chat_v2({
        conversacionId: currentId!,
        content: payload.content,
        campos: payload.campos,
      })

      return { ...result, conversacionId: currentId }
    },
    onSuccess: (data) => {
      // Invalidamos mensajes para que se refresque el chat
      qc.invalidateQueries({
        queryKey: ['subject-messages', data.conversacionId],
      })
    },
  })
}

export function useConversationBySubject(subjectId: string | null) {
  return useQuery({
    queryKey: ['conversation-by-subject', subjectId],
    queryFn: () => getConversationBySubject(subjectId!),
    enabled: !!subjectId,
  })
}

export function useMessagesBySubjectChat(conversationId: string | null) {
  const queryClient = useQueryClient()

  const query = useQuery({
    queryKey: ['subject-messages', conversationId],
    queryFn: async () => {
      if (!conversationId) throw new Error('Conversation ID is required')
      return getMessagesBySubjectConversation(conversationId)
    },
    enabled: !!conversationId,
    placeholderData: (previousData) => previousData,
  })

  useEffect(() => {
    if (!conversationId) return

    const supabase = supabaseBrowser()

    // Suscripción a cambios en la tabla específica para esta conversación
    const channel = supabase
      .channel(`subject_messages_${conversationId}`)
      .on(
        'postgres_changes',
        {
          event: 'UPDATE', // Solo nos interesan las actualizaciones (cuando pasa de PROCESANDO a COMPLETADO)
          schema: 'public',
          table: 'asignatura_mensajes_ia',
          filter: `conversacion_asignatura_id=eq.${conversationId}`,
        },
        (payload) => {
          // Si el mensaje se completó o dio error, invalidamos la caché para traer los datos nuevos
          if (
            payload.new.estado === 'COMPLETADO' ||
            payload.new.estado === 'ERROR'
          ) {
            queryClient.invalidateQueries({
              queryKey: ['subject-messages', conversationId],
            })
          }
        },
      )
      .subscribe()

    return () => {
      supabase.removeChannel(channel)
    }
  }, [conversationId, queryClient])

  return query
}

export function useUpdateSubjectRecommendation() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: (payload: { mensajeId: string; campoAfectado: string }) =>
      update_subject_recommendation_applied(
        payload.mensajeId,
        payload.campoAfectado,
      ),
    onSuccess: () => {
      // Refrescamos los mensajes para ver el check de "aplicado"
      qc.invalidateQueries({ queryKey: ['subject-messages'] })
    },
  })
}

export function useUpdateSubjectConversationStatus() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: (payload: { id: string; estado: 'ARCHIVADA' | 'ACTIVA' }) =>
      update_subject_conversation_status(payload.id, payload.estado),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['conversation-by-subject'] })
    },
  })
}

export function useUpdateSubjectConversationName() {
  const qc = useQueryClient()

  return useMutation({
    mutationFn: (payload: { id: string; nombre: string }) =>
      update_subject_conversation_name(payload.id, payload.nombre),
    onSuccess: () => {
      qc.invalidateQueries({ queryKey: ['conversation-by-subject'] })
      // También invalidamos los mensajes si el título se muestra en la cabecera
      qc.invalidateQueries({ queryKey: ['subject-messages'] })
    },
  })
}
