// Third-party Imports
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit'
import type { PayloadAction } from '@reduxjs/toolkit'

// Type Imports
import type { StatusType, ContactType, ChatType, ProfileUserType } from '@/types/apps/chatTypes'

// API Imports
import { chatService } from '@/libs/api'

// Async Thunks
export const fetchContacts = createAsyncThunk('chat/fetchContacts', async () => {
  return await chatService.getContacts()
})

export const fetchConversations = createAsyncThunk('chat/fetchConversations', async () => {
  return await chatService.getConversations()
})

export const fetchProfile = createAsyncThunk('chat/fetchProfile', async () => {
  return await chatService.getProfile()
})

export const fetchMessages = createAsyncThunk(
  'chat/fetchMessages',
  async ({ conversationId, page, limit }: { conversationId: number; page?: number; limit?: number }) => {
    return await chatService.getMessages(conversationId, page, limit)
  }
)

export const sendMessage = createAsyncThunk(
  'chat/sendMessage',
  async ({ conversationId, message }: { conversationId: number; message: string }) => {
    return await chatService.sendMessage(conversationId, message)
  }
)

const initialState: {
  contacts: ContactType[]
  chats: ChatType[]
  activeUser: ContactType | null
  profileUser: ProfileUserType | null
  loading: boolean
  error: string | null
} = {
  contacts: [],
  chats: [],
  activeUser: null,
  profileUser: null,
  loading: false,
  error: null
}

export const chatSlice = createSlice({
  name: 'chat',
  initialState,
  reducers: {
    getActiveUserData: (state, action: PayloadAction<number>) => {
      const activeUser = state.contacts.find(user => user.id === action.payload)

      const chat = state.chats.find(chat => chat.userId === action.payload)

      if (chat && chat.unseenMsgs > 0) {
        chat.unseenMsgs = 0
      }

      if (activeUser) {
        state.activeUser = activeUser
      }
    },

    addNewChat: (state, action) => {
      const { id } = action.payload

      state.contacts.find(contact => {
        if (contact.id === id && !state.chats.find(chat => chat.userId === contact.id)) {
          state.chats.unshift({
            id: state.chats.length + 1,
            userId: contact.id,
            unseenMsgs: 0,
            chat: []
          })
        }
      })
    },

    setUserStatus: (state, action: PayloadAction<{ status: StatusType }>) => {
      if (state.profileUser) {
        state.profileUser = {
          ...state.profileUser,
          status: action.payload.status
        }
      }
    },

    addMessageToChat: (state, action: PayloadAction<{ conversationId: number; message: any }>) => {
      const { conversationId, message } = action.payload
      const chat = state.chats.find(chat => chat.id === conversationId)
      if (chat) {
        // Ensure chat.chat is an array
        if (!chat.chat || !Array.isArray(chat.chat)) {
          chat.chat = []
        }
        chat.chat.push(message)
        // Move chat to top
        state.chats = state.chats.filter(c => c.id !== conversationId)
        state.chats.unshift(chat)
      }
    }
  },
  extraReducers: builder => {
    builder
      // Fetch Contacts
      .addCase(fetchContacts.pending, state => {
        state.loading = true
        state.error = null
      })
      .addCase(fetchContacts.fulfilled, (state, action) => {
        state.loading = false
        state.contacts = action.payload
      })
      .addCase(fetchContacts.rejected, (state, action) => {
        state.loading = false
        state.error = action.error.message || 'Failed to fetch contacts'
      })
      // Fetch Conversations
      .addCase(fetchConversations.pending, state => {
        state.loading = true
        state.error = null
      })
      .addCase(fetchConversations.fulfilled, (state, action) => {
        state.loading = false
        // Ensure each chat has a chat array
        state.chats = action.payload.map(chat => ({
          ...chat,
          chat: Array.isArray(chat.chat) ? chat.chat : []
        }))
      })
      .addCase(fetchConversations.rejected, (state, action) => {
        state.loading = false
        state.error = action.error.message || 'Failed to fetch conversations'
      })
      // Fetch Profile
      .addCase(fetchProfile.pending, state => {
        state.loading = true
        state.error = null
      })
      .addCase(fetchProfile.fulfilled, (state, action) => {
        state.loading = false
        state.profileUser = action.payload
      })
      .addCase(fetchProfile.rejected, (state, action) => {
        state.loading = false
        state.error = action.error.message || 'Failed to fetch profile'
      })
      // Send Message
      .addCase(sendMessage.fulfilled, (state, action) => {
        const message = action.payload
        const chat = state.chats.find(chat => chat.userId === state.activeUser?.id)
        if (chat) {
          // Ensure chat.chat is an array
          if (!chat.chat || !Array.isArray(chat.chat)) {
            chat.chat = []
          }
          chat.chat.push({
            message: message.message,
            time: message.time,
            senderId: message.senderId,
            msgStatus: message.msgStatus
          })
          // Move chat to top
          state.chats = state.chats.filter(c => c.id !== chat.id)
          state.chats.unshift(chat)
        }
      })
  }
})

export const { getActiveUserData, addNewChat, setUserStatus, addMessageToChat } = chatSlice.actions

export default chatSlice.reducer
