import { createSelector, createSlice, PayloadAction } from '@reduxjs/toolkit'
import { AIFeatureModel, AIFeaturesModel, AIFeaturesStatus } from './models'
import {
  AIFeature,
  AIFeatureType,
  AIResult,
  QuestionAnswerConfig,
  QuestionAnswerResult,
  TopicDetectionConfig,
  TopicDetectionResult,
} from '@zocks-communications/client-sdk-js'
import { RootState } from '../../app/store'
import { ErrorResponse } from '../../components'

const initialState: AIFeaturesModel = {
  aiFeaturesStatus: AIFeaturesStatus.INITIAL,
  aiFeatures: {},
  errors: [],
}

export const aiFeatureSlice = createSlice({
  name: 'aiFeature',
  initialState,
  reducers: {
    initAIFeatures: (state, action: PayloadAction<AIFeature[]>) => {
      action.payload.forEach((aiFeature) => {
        state.aiFeatures[aiFeature.id] = { ...aiFeature, results: [] }
      })
      state.aiFeaturesStatus = AIFeaturesStatus.SUCCESS
    },
    initAIResults: (state, action: PayloadAction<AIResult[]>) => {
      action.payload.forEach((aiResult) => {
        const aiFeature = state.aiFeatures[aiResult.aiFeatureId]
        if (aiFeature) {
          aiFeature.results.push(aiResult)
        }
      })
      state.aiFeaturesStatus = AIFeaturesStatus.SUCCESS
    },
    setAIFeaturesStatus: (state, action: PayloadAction<AIFeaturesStatus>) => {
      state.aiFeaturesStatus = action.payload
    },
    clearAIFeatures: (state) => {
      state.aiFeatures = {}
      state.aiFeaturesStatus = AIFeaturesStatus.IDLE
    },
    setAIFeaturesError: (state, action: PayloadAction<ErrorResponse>) => {
      state.aiFeaturesStatus = AIFeaturesStatus.ERROR
      state.errors = action.payload.errors
    },
    aiResultReceived: (state, action: PayloadAction<AIResult>) => {
      const { aiFeatureId, result } = action.payload
      const aiFeature = state.aiFeatures[aiFeatureId]
      if (!aiFeature || !result) {
        return
      }
      switch (true) {
        case result.type === AIFeatureType.TOPIC_DETECTION:
          handleTopicDetectionAIResultReceived(aiFeature, action.payload)
          return
        case result.type === AIFeatureType.QUESTION_ANSWER:
          handleQuestionAnswerAIResultReceived(aiFeature, action.payload)
          return
        default:
          aiFeature.results.push(action.payload)
      }
    },
  },
})

const handleTopicDetectionAIResultReceived = (aiFeature: AIFeatureModel, aiResult: AIResult) => {
  const topicDetectionResult = aiResult.result as TopicDetectionResult
  const config = aiFeature.config as TopicDetectionConfig
  if (config.topics.includes(topicDetectionResult.detectedTopic)) {
    aiFeature.results.push(aiResult)
  }
}

const handleQuestionAnswerAIResultReceived = (aiFeature: AIFeatureModel, aiResult: AIResult) => {
  const questionAnswerResult = aiResult.result as QuestionAnswerResult
  const config = aiFeature.config as QuestionAnswerConfig
  if (config.questions.some((q) => q.id === questionAnswerResult.questionId)) {
    aiFeature.results.push(aiResult)
  }
}

export const {
  initAIFeatures,
  initAIResults,
  setAIFeaturesError,
  setAIFeaturesStatus,
  clearAIFeatures,
  aiResultReceived,
} = aiFeatureSlice.actions
export const selectAIFeatures = createSelector(
  [(state) => state.aiFeature.aiFeatures],
  (aiFeatures): AIFeatureModel[] => {
    return Object.values(aiFeatures)
  }
)
export const selectAIFeaturesStatus = (state: RootState): AIFeaturesStatus => state.aiFeature.aiFeaturesStatus
export default aiFeatureSlice.reducer
