import { configureStore } from '@reduxjs/toolkit'
import {
  ComponentFilter,
  SeamlyApiContext,
  SeamlyEventBusContext,
  SeamlyLiveRegionContext,
  SeamlyStoreProvider,
  SeamlyFileUpload,
  API,
  configReducer,
  appReducer,
  setConfig,
  setPreChatEvents,
  formsReducer,
  I18nState,
  i18nReducer,
  setInitialLocale,
  setTranslations,
  interruptReducer,
  stateReducer,
  setParticipant,
  MessageParticipant,
  StoreState,
  ReduxStore,
  translationReducer,
  visibilityReducer,
  SeamlyActivityEventContext,
} from '@seamly/web-ui'
import { FC } from 'preact/compat'
import { useMemo, useRef } from 'preact/hooks'

const bareApi = {
  send: () => {
    // do nothing
  },
  store: {
    get: (key: string) => key,
    set: (key: string) => key,
    delete: (key: string) => key,
  },
  sendContext: () => {},
  hasConversation: () => false,
  connected: false,
} satisfies Partial<API>

type StaticCoreProps = {
  state: StoreState & Omit<ReduxStore, 'state' | 'i18n' | 'forms'>
  translations: I18nState['translations']
  participants: MessageParticipant['participant'][]
}

const SeamlyStaticCore: FC<StaticCoreProps> = ({
  state,
  translations,
  participants = [],
  children,
}) => {
  const liveMsgRef = useRef(() => {
    // do nothing
  })
  const eventBusRef = useRef({
    emit: () => {
      // do nothing
    },
    on: () => {
      // do nothing
    },
    off: () => {
      // do nothing
    },
  })

  const store = useMemo(() => {
    const {
      translations: initialTranslations,
      interrupt: initialInterrupt,
      config: initialConfig,
      visibility: initialVisibility,
      ...initialState
    } = state || {}

    const newStore = configureStore({
      reducer: {
        state: stateReducer,
        app: appReducer,
        config: configReducer,
        i18n: i18nReducer,
        translations: translationReducer,
        visibility: visibilityReducer,
        forms: formsReducer,
        interrupt: interruptReducer,
      },
      preloadedState: {
        state: initialState,
        config: initialConfig,
        translations: initialTranslations,
        interrupt: initialInterrupt,
        visibility: initialVisibility,
      },
      middleware: (getDefaultMiddleWare) =>
        getDefaultMiddleWare({
          thunk: {
            extraArgument: {
              api: bareApi,
              eventBus: eventBusRef.current,
            },
          },
          serializableCheck: false,
        }),
    })

    const { config } = newStore.getState()
    newStore.dispatch(setConfig(config))
    if (config.preChatEvents) {
      newStore.dispatch(setPreChatEvents(config.preChatEvents))
    }
    newStore.dispatch(setInitialLocale('en-GB'))
    newStore.dispatch(setTranslations(translations))

    participants.forEach((participant) => {
      newStore.dispatch(
        setParticipant({
          participant,
          fromClient: participant?.id === 'user',
        }),
      )
    })

    return newStore
  }, [participants, state, translations])

  return (
    state && (
      <SeamlyStoreProvider store={store}>
        <SeamlyEventBusContext.Provider value={eventBusRef.current}>
          {/* @ts-ignore */}
          <SeamlyApiContext.Provider value={bareApi}>
            <SeamlyLiveRegionContext.Provider value={liveMsgRef.current}>
              <ComponentFilter>
                <SeamlyActivityEventContext.Provider value={() => {}}>
                  <SeamlyFileUpload>{children}</SeamlyFileUpload>
                </SeamlyActivityEventContext.Provider>
              </ComponentFilter>
            </SeamlyLiveRegionContext.Provider>
          </SeamlyApiContext.Provider>
        </SeamlyEventBusContext.Provider>
      </SeamlyStoreProvider>
    )
  )
}

export default SeamlyStaticCore
