'use client'

import type { FC, PropsWithChildren } from 'react'
import type { ChatConfig } from '@/app/components/base/chat/types'
import type { AppData, AppMeta } from '@/models/share'
import { useQuery } from '@tanstack/react-query'
import { useEffect } from 'react'
import { create } from 'zustand'
import { getProcessedSystemVariablesFromUrlParams } from '@/app/components/base/chat/utils'
import Loading from '@/app/components/base/loading'
import { AccessMode } from '@/models/access-control'
import { usePathname, useSearchParams } from '@/next/navigation'
import { systemFeaturesQueryOptions } from '@/service/system-features'
import { useGetWebAppAccessModeByCode } from '@/service/use-share'

type WebAppStore = {
  shareCode: string | null
  updateShareCode: (shareCode: string | null) => void
  appInfo: AppData | null
  updateAppInfo: (appInfo: AppData | null) => void
  appParams: ChatConfig | null
  updateAppParams: (appParams: ChatConfig | null) => void
  webAppAccessMode: AccessMode
  updateWebAppAccessMode: (accessMode: AccessMode) => void
  appMeta: AppMeta | null
  updateWebAppMeta: (appMeta: AppMeta | null) => void
  userCanAccessApp: boolean
  updateUserCanAccessApp: (canAccess: boolean) => void
  embeddedUserId: string | null
  updateEmbeddedUserId: (userId: string | null) => void
  embeddedConversationId: string | null
  updateEmbeddedConversationId: (conversationId: string | null) => void
}

export const useWebAppStore = create<WebAppStore>(set => ({
  shareCode: null,
  updateShareCode: (shareCode: string | null) => set(() => ({ shareCode })),
  appInfo: null,
  updateAppInfo: (appInfo: AppData | null) => set(() => ({ appInfo })),
  appParams: null,
  updateAppParams: (appParams: ChatConfig | null) => set(() => ({ appParams })),
  webAppAccessMode: AccessMode.SPECIFIC_GROUPS_MEMBERS,
  updateWebAppAccessMode: (accessMode: AccessMode) => set(() => ({ webAppAccessMode: accessMode })),
  appMeta: null,
  updateWebAppMeta: (appMeta: AppMeta | null) => set(() => ({ appMeta })),
  userCanAccessApp: false,
  updateUserCanAccessApp: (canAccess: boolean) => set(() => ({ userCanAccessApp: canAccess })),
  embeddedUserId: null,
  updateEmbeddedUserId: (userId: string | null) => set(() => ({ embeddedUserId: userId })),
  embeddedConversationId: null,
  updateEmbeddedConversationId: (conversationId: string | null) =>
    set(() => ({ embeddedConversationId: conversationId })),
}))

const getShareCodeFromRedirectUrl = (redirectUrl: string | null): string | null => {
  if (!redirectUrl || redirectUrl.length === 0)
    return null
  const url = new URL(`${window.location.origin}${decodeURIComponent(redirectUrl)}`)
  return url.pathname.split('/').pop() || null
}
const getShareCodeFromPathname = (pathname: string): string | null => {
  const code = pathname.split('/').pop() || null
  if (code === 'webapp-signin')
    return null
  return code
}

const WebAppStoreProvider: FC<PropsWithChildren> = ({ children }) => {
  const { isPending: isGlobalPending } = useQuery(systemFeaturesQueryOptions())
  const updateWebAppAccessMode = useWebAppStore(state => state.updateWebAppAccessMode)
  const updateShareCode = useWebAppStore(state => state.updateShareCode)
  const updateEmbeddedUserId = useWebAppStore(state => state.updateEmbeddedUserId)
  const updateEmbeddedConversationId = useWebAppStore(state => state.updateEmbeddedConversationId)
  const pathname = usePathname()
  const searchParams = useSearchParams()
  const redirectUrlParam = searchParams.get('redirect_url')
  const searchParamsString = searchParams.toString()

  // Compute shareCode directly
  const shareCode = getShareCodeFromRedirectUrl(redirectUrlParam) || getShareCodeFromPathname(pathname)
  useEffect(() => {
    updateShareCode(shareCode)
  }, [shareCode, updateShareCode])

  useEffect(() => {
    let cancelled = false
    const syncEmbeddedUserId = async () => {
      try {
        const { user_id, conversation_id } = await getProcessedSystemVariablesFromUrlParams()
        if (!cancelled) {
          updateEmbeddedUserId(user_id || null)
          updateEmbeddedConversationId(conversation_id || null)
        }
      }
      catch {
        if (!cancelled) {
          updateEmbeddedUserId(null)
          updateEmbeddedConversationId(null)
        }
      }
    }
    syncEmbeddedUserId()
    return () => {
      cancelled = true
    }
  }, [searchParamsString, updateEmbeddedUserId, updateEmbeddedConversationId])

  const { isLoading, data: accessModeResult } = useGetWebAppAccessModeByCode(shareCode)

  useEffect(() => {
    if (accessModeResult?.accessMode)
      updateWebAppAccessMode(accessModeResult.accessMode)
  }, [accessModeResult, updateWebAppAccessMode, shareCode])

  if (isGlobalPending || isLoading) {
    return (
      <div className="flex size-full items-center justify-center">
        <Loading />
      </div>
    )
  }
  return (
    <>
      {children}
    </>
  )
}
export default WebAppStoreProvider
