import type React from 'react'
import { useCallback, useEffect, useRef, useState } from 'react'
import { motion } from 'framer-motion'
import { Outlet, useLocation } from 'react-router-dom'
import { useLocalStorageState } from 'ahooks'
import styles from './Home.module.less'
import { QuestionList } from './components/QuestionList'
import HomeIcon2 from '@/assets/homeIcon2.png'
import SmartIce from '@/assets/smart-ice.png'
import { clearBusinessInsightWorkflow, clearCurrentToolId, fetchConversations, setCurrentConversation, setCurrentToolId, setNavigationFlag } from '@/store/conversationSlice'
import { useAppDispatch, useAppSelector } from '@/store/hook'
import { fetchEfficiencyQuestionList } from '@/api/home'
import SdreamLoading from '@/components/SdreamLoading'
import { fetchLoginByToken, fetchLoginByUid } from '@/api/common'
import { fetchSessionConversationId } from '@/api/conversation'
import { fetchBusinessInsightList, fetchCheckTokenApi } from '@/api/chat'
import { getUserRolesFromRoute, safeLocalStorageGetItem, safeLocalStorageSetItem, safeSessionStorageGetItem, safeSessionStorageRemoveItem, safeSessionStorageSetItem, waitForToken } from '@/lib/utils'
import {
  findToolRowBySessionToolId,
  getBusinessInsightConfigTypesForRow,
  getCommonQuestionRecordTypeForToolRow,
  readToolListFromSessionStorage,
  toolRowUsesBusinessInsightCommonQuestions,
} from '@/lib/toolRoleRecordTypes'

// 从 localStorage 获取 token 的辅助函数
function getTokenFromStorage(): string | null {
  const tokenStr = safeLocalStorageGetItem('__TOKEN__')
  if (!tokenStr) {
    return null
  }
  try {
    // useLocalStorageState 会将值序列化为 JSON，需要解析
    const parsed = JSON.parse(tokenStr)
    return parsed || tokenStr
  }
  catch {
    // 如果不是 JSON 格式，直接使用原始值
    return tokenStr
  }
}

function getAnimationProps(delay: number) {
  return {
    variants: {
      hidden: {
        opacity: 0,
        y: 50,
        scale: 0.9,
        rotateX: -6,
      },
      visible: {
        opacity: 1,
        y: 0,
        scale: 1,
        rotateX: 0,
        transition: {
          duration: 0.4,
          delay: delay * 0.1,
          ease: [0.25, 0.1, 0.25, 1],
        },
      },
    },
    initial: 'hidden',
    animate: 'visible',
  }
}

// 已移除 sessionStorage 标志，改为仅使用组件级保护，确保每次打开链接都能调用 SSO 登录

export const Home: React.FC = () => {
  const viteOutputObj = import.meta.env.VITE_OUTPUT_OBJ || 'open'
  const [isLoading, _setIsLoading] = useState(false)
  const [isDataLoaded, setIsDataLoaded] = useState(false)
  const dispatch = useAppDispatch()
  const location = useLocation()
  const currentConversationId = useAppSelector(state => state.conversation.currentConversationId)
  const businessInsightConfigTypesRef = useRef<string[]>(['10'])
  const hasFetched = useRef(false)
  const hasCalledBusinessApis = useRef(false) // 防止业务接口重复调用
  const prevPathRef = useRef<string>(location.pathname) // 记录上一次路径，用于检测从收藏页面返回
  // 使用 useState
  const [otherQuestions, setOtherQuestions] = useState<any>({ content: [] })
  const [isToolBtnActive, setIsToolBtnActive] = useState<boolean>(false)
  const [shouldChangeStyle, setShouldChangeStyle] = useState<boolean>(true)
  const [isBusinessInsightMode, setIsBusinessInsightMode] = useState<boolean>(false)
  // 保存原始的configType为07的数据
  const [originalOtherQuestions, _setOriginalOtherQuestions] = useState<any>({ content: [] })

  const [token, setToken] = useLocalStorageState<string | undefined>('__TOKEN__', {
    defaultValue: '',
  })

  const [_userName, setUserName] = useLocalStorageState<string | undefined>('__USER_NAME__', {
    defaultValue: '',
  })

  const parseBusinessInsightQuestions = (rawContent: unknown): string[] => {
    if (Array.isArray(rawContent)) {
      return rawContent.filter((item): item is string => typeof item === 'string').map(item => item.trim()).filter(Boolean)
    }
    if (typeof rawContent === 'string') {
      try {
        const parsed = JSON.parse(rawContent)
        if (Array.isArray(parsed)) {
          return parsed.filter((item): item is string => typeof item === 'string').map(item => item.trim()).filter(Boolean)
        }
      }
      catch {
        return []
      }
    }
    return []
  }

  const fetchBusinessInsightQuestions = useCallback(async () => {
    const res = await fetchBusinessInsightList({ configTypeList: businessInsightConfigTypesRef.current })
    const data = Array.isArray(res?.data) ? res.data[0] : res?.data
    const normalized = parseBusinessInsightQuestions(data?.content ?? data?.questionList)
    setOtherQuestions((prev: any) => ({
      ...prev,
      configName: data?.configName || '业务洞察',
      content: normalized,
    }))
  }, [])

  const resolveCommonQuestionRecordType = useCallback(async (sessionToolId: string): Promise<string> => {
    const list = readToolListFromSessionStorage()
    const row = findToolRowBySessionToolId(list, sessionToolId)
    return getCommonQuestionRecordTypeForToolRow(row) || '01'
  }, [])

  // 获取会话ID并加载历史记录
  const getSessionConversationId = async (data?: any): Promise<string | null> => {
    try {
      // 等待 token 就绪后再调用接口
      await waitForToken()
      // 从 sessionStorage 获取 toolId 作为 busiId
      const toolId = safeSessionStorageGetItem('currentToolId') || ''
      const requestData = {
        ...(data || {}),
        busiId: toolId,
      }
      const res = await fetchSessionConversationId(requestData)
      if (res?.data?.conversationId) {
        const conversationId = res.data.conversationId
        dispatch(setCurrentConversation(conversationId))
        dispatch(setNavigationFlag(true))

        // 历史记录会在 Chat 页面自动渲染，不需要在这里获取
        // 移除重复调用，避免接口被调用两次
        return conversationId
      }
      return null
    }
    catch (error) {
      console.error('获取会话ID失败:', error)
      return null
    }
  }

  // 刷新问题列表
  const handleRefreshQuestions = useCallback(async () => {
    // 先清空旧数据
    setOtherQuestions((prev: any) => ({
      ...prev,
      content: [],
    }))
    setIsDataLoaded(false) // 重置加载状态

    try {
      if (isBusinessInsightMode) {
        await fetchBusinessInsightQuestions()
        return
      }

      // 从路由中获取 conversationId
      const conversationId = location.pathname.startsWith('/chat/')
        ? location.pathname.split('/')[2]
        : null

      if (!conversationId) {
        setIsDataLoaded(true)
        return
      }

      const toolId = safeSessionStorageGetItem('currentToolId') || ''
      const recordType = await resolveCommonQuestionRecordType(toolId)

      const res = await fetchEfficiencyQuestionList({
        conversationId,
        busiType: '01',
        recordType,
      })
      if (res && res.data && res.data.questionList) {
        setOtherQuestions((prev: any) => ({
          ...prev,
          content: res.data.questionList || [],
        }))
      }
    }
    catch (error) {
      console.error('[HomeNew] handleRefreshQuestions - 刷新问题列表失败:', error)
      throw error // 抛出错误，让 QuestionList 组件处理
    }
    finally {
      setIsDataLoaded(true) // 无论成功失败都标记为已加载
    }
  }, [location.search, isBusinessInsightMode, fetchBusinessInsightQuestions, resolveCommonQuestionRecordType])

  // 处理工具按钮点击
  const _handleToolClick = useCallback(async (isToolBtn: boolean, toolId?: string, ignoreUrlToolId?: boolean, conversationIdParam?: string | null) => {
    // 提质增效模式 / 数据助手 / 制度活化：都先清空数据，重新拉常见问题
    setIsBusinessInsightMode(false)
    setOtherQuestions((prev: any) => ({
      ...prev,
      content: [],
    }))
    setIsDataLoaded(false) // 重置加载状态
    try {
      const storedToolId = safeSessionStorageGetItem('currentToolId') || ''
      // 首页初始化加载常见问题时，允许忽略路由中的 toolId，避免带入上一次的工具 ID
      const shouldForceClearToolId = !storedToolId

      let finalToolId = toolId || ''

      // 场景：首页首次挂载（ignoreUrlToolId === true）且为制度活化（!isToolBtn && !toolId）
      // 此时无论 sessionStorage 中是否残留上一次的 toolId，都强制使用空字符串，避免带入历史工具 ID
      if (ignoreUrlToolId && !isToolBtn && !toolId) {
        finalToolId = ''
      }
      else if (shouldForceClearToolId && !isToolBtn) {
        finalToolId = ''
      }
      else if (!finalToolId && !isToolBtn) {
        // 仅在工具模式下才使用回退逻辑，避免制度活化误用上一次的 toolId
        finalToolId = storedToolId
      }

      // 优先使用传入的 conversationId，其次从 Redux 获取，最后从路由中获取
      const conversationId = conversationIdParam || currentConversationId || (location.pathname.startsWith('/chat/')
        ? location.pathname.split('/')[2]
        : null)

      if (!conversationId) {
        setIsDataLoaded(true)
        return
      }

      const currentToolId = safeSessionStorageGetItem('currentToolId') || ''
      const recordType = await resolveCommonQuestionRecordType(currentToolId)

      // 调用真实 API 获取常见问题列表
      const res = await fetchEfficiencyQuestionList({
        conversationId,
        busiType: '01',
        recordType,
      })
      if (res && res.data && res.data.questionList) {
        setOtherQuestions((prev: any) => ({
          ...prev,
          content: res.data.questionList || [],
        }))
      }
    }
    catch (error) {
      console.error('获取工具相关问题失败:', error)
    }
    finally {
      setIsDataLoaded(true) // 无论成功失败都标记为已加载
    }
  }, [originalOtherQuestions, location.search, location.pathname, currentConversationId, resolveCommonQuestionRecordType])

  // 监听工具按钮点击事件
  useEffect(() => {
    const handleToolClickEvent = (event: CustomEvent) => {
      const { isToolBtn, toolId, conversationId, source } = event.detail
      setIsToolBtnActive(isToolBtn)
      // 更新样式控制状态
      setShouldChangeStyle(true)

      // 保存当前选择的 toolId 到 Redux
      if (!isToolBtn && toolId) {
        // 提质增效模式，保存 toolId
        dispatch(setCurrentToolId(toolId))
      }
      else {
        // 制度活化，清除 toolId
        dispatch(clearCurrentToolId())
      }

      const list = readToolListFromSessionStorage()
      const rowForTool = findToolRowBySessionToolId(list, toolId || '')
      const isBusinessInsightClick = source === 'toolButton' && toolRowUsesBusinessInsightCommonQuestions(rowForTool)

      if (isBusinessInsightClick) {
        setIsBusinessInsightMode(true)
        dispatch(clearBusinessInsightWorkflow())
        businessInsightConfigTypesRef.current = getBusinessInsightConfigTypesForRow(rowForTool)
        // 先清空旧数据
        setOtherQuestions((prev: any) => ({
          ...prev,
          content: [],
        }))
        setIsDataLoaded(false)

        fetchBusinessInsightQuestions()
          .catch(() => {
            console.error('[HomeNew] 业务洞察常见问题获取失败')
          })
          .finally(() => {
            setIsDataLoaded(true)
          })
        return
      }

      setIsBusinessInsightMode(false)

      // 如果事件传递了 conversationId，延迟调用以确保路由更新完成
      // 延迟一小段时间（100ms）确保 React Router 已完成路由更新和状态同步
      if (conversationId) {
        setTimeout(() => {
          _handleToolClick(isToolBtn, toolId, false, conversationId)
        }, 100)
      }
      else {
        // 如果没有传递 conversationId，立即调用（保持原有逻辑）
        _handleToolClick(isToolBtn, toolId, false, conversationId)
      }
    }
    window.addEventListener('toolButtonClick', handleToolClickEvent as EventListener)
    return () => {
      window.removeEventListener('toolButtonClick', handleToolClickEvent as EventListener)
    }
  }, [_handleToolClick, isToolBtnActive, shouldChangeStyle, dispatch, fetchBusinessInsightQuestions])

  // 监听从收藏返回时刷新问题列表的事件
  useEffect(() => {
    const handleRefreshQuestionsFromCollect = (event: CustomEvent) => {
      const { toolId } = event.detail
      // 如果传递了 toolId，先更新 sessionStorage，确保刷新时使用正确的 toolId
      if (toolId) {
        safeSessionStorageSetItem('currentToolId', toolId)
      }
      // 刷新问题列表，会调用 generate_question 接口
      handleRefreshQuestions()
    }
    window.addEventListener('refreshQuestionsFromCollect', handleRefreshQuestionsFromCollect as EventListener)
    return () => {
      window.removeEventListener('refreshQuestionsFromCollect', handleRefreshQuestionsFromCollect as EventListener)
    }
  }, [handleRefreshQuestions])

  const login = useCallback(async () => {
    // 防止重复调用（组件级别保护，每次组件挂载时会重置，确保每次打开链接都能调用）
    if (hasFetched.current) {
      return
    }
    const url = new URL(window.location.href)
    // 获取查询参数
    const searchParams = new URLSearchParams(url.search)
    const from = searchParams.get('from')
    const _loginCode = searchParams.get('loginCode')

    // 如果有 loginCode，执行 SSO 登录（包括 from=tactics 的情况）
    if (_loginCode && viteOutputObj === 'inner') {
      // 立即设置标志，防止重复执行（仅组件级别，每次组件挂载时会重置）
      hasFetched.current = true
      // 每次进入页面调用 sso_login 时，先清空 sessionStorage 中的 currentToolId
      // 避免关闭标签页后再次打开时使用上次的历史 toolId
      safeSessionStorageRemoveItem('currentToolId')
      try {
        const res = await fetchLoginByToken(_loginCode)
        if (res.data) {
          // 登录成功后先清理旧状态，避免沿用上一次的工具模式
          dispatch(clearCurrentToolId())
          safeSessionStorageRemoveItem('currentToolId')
          const currentUrl = new URL(window.location.href)
          if (currentUrl.searchParams.has('toolId')) {
            currentUrl.searchParams.delete('toolId')
            // 使用 replace 避免产生新的历史记录
            window.history.replaceState({}, '', currentUrl.toString())
          }
          // 尝试使用 useLocalStorageState 设置 token，如果失败则使用降级方案
          try {
            setToken(res.data.token)
          }
          catch (error) {
            // localStorage 被阻止时，使用安全函数降级存储
            console.warn('setToken 失败，使用降级方案:', error)
            try {
              safeLocalStorageSetItem('__TOKEN__', JSON.stringify(res.data.token))
            }
            catch (storageError) {
              console.error('降级存储也失败:', storageError)
            }
          }
          if (res.data.userId) {
            try {
              setUserName(res.data.userId)
            }
            catch {
              // userId 存储失败时使用降级方案
              try {
                safeLocalStorageSetItem('__USER_NAME__', JSON.stringify(res.data.userId))
              }
              catch (storageError) {
                console.error('userId 降级存储失败:', storageError)
              }
            }
          }
          // 确保 token 已写入 localStorage（useLocalStorageState 是同步的，但为了保险起见，使用微任务确保写入完成）
          await new Promise(resolve => setTimeout(resolve, 0))
          // 验证 token 是否真正写入，如果没有则使用降级方案
          const verifyToken = getTokenFromStorage()
          if (!verifyToken) {
            // 如果 useLocalStorageState 写入失败，使用安全函数再次尝试
            try {
              safeLocalStorageSetItem('__TOKEN__', JSON.stringify(res.data.token))
            }
            catch (storageError) {
              console.error('token 验证后降级存储失败:', storageError)
            }
          }
          window.dispatchEvent(
            new StorageEvent('storage', {
              key: '__TOKEN__',
              oldValue: token,
              newValue: res.data.token,
              url: window.location.href,
              storageArea: localStorage,
            }),
          )
          // 如果是 from=tactics，只执行登录，不执行其他业务逻辑（由 TacticsHome 处理）
          if (from !== 'tactics') {
            console.log('homeNew sso555555')
            // 确保 token 已写入 localStorage 后再调用业务接口
            const actualToken = getTokenFromStorage() || res.data.token
            if (actualToken && !hasCalledBusinessApis.current) {
              hasCalledBusinessApis.current = true
              // 触发自定义事件，通知 ChatEditor 强制重置为制度活化
              window.dispatchEvent(new CustomEvent('forceResetToGeneralMode'))
              const conversationId = await getSessionConversationId()
              dispatch(fetchConversations())
              // 2. 拉取常见问题等业务数据
              _handleToolClick(false, '', true, conversationId)
            }
          }
        }
      }
      catch (error) {
        console.error('SSO 登录失败:', error)
        // 登录失败时清除标志，允许重试
        hasFetched.current = false
      }
      return
    }

    // 如果没有 loginCode，执行其他逻辑（非 from=tactics 的情况）
    if (from !== 'tactics') {
    console.log('homeNew sso666666')
      hasFetched.current = true
      if (viteOutputObj === 'inner') {
        // inner 环境下，如果没有 loginCode，先验证 token 是否有效
        // 保证登录成功（token 有效）后再调用业务接口
        const existingToken = getTokenFromStorage()
        if (existingToken && !hasCalledBusinessApis.current) {
          try {
            // 验证 token 是否有效
            await fetchCheckTokenApi()
            // token 验证成功，调用业务接口
            hasCalledBusinessApis.current = true
            // 等待获取会话ID后再调用 _handleToolClick
            const conversationId = await getSessionConversationId()
            dispatch(fetchConversations())
            // 拉取常见问题等业务数据
            _handleToolClick(false, '', true, conversationId)
          }
          catch (error) {
            // token 验证失败，不调用业务接口
            console.error('Token 验证失败:', error)
          }
        }
        // 如果没有 token，不调用业务接口，等待 loginCode 或用户手动登录
      }
      else {
        // 模拟登录 可以用来测试
        try {
          const res = await fetchLoginByUid('123123')
          if (res.data) {
            // 登录成功后先清理旧状态，避免沿用上一次的工具模式
            dispatch(clearCurrentToolId())
            safeSessionStorageRemoveItem('currentToolId')
            const currentUrl = new URL(window.location.href)
            if (currentUrl.searchParams.has('toolId')) {
              currentUrl.searchParams.delete('toolId')
              window.history.replaceState({}, '', currentUrl.toString())
            }
            // 尝试使用 useLocalStorageState 设置 token，如果失败则使用降级方案
            try {
              setToken(res.data.token)
            }
            catch (error) {
              // localStorage 被阻止时，使用安全函数降级存储
              console.warn('setToken 失败，使用降级方案:', error)
              try {
                safeLocalStorageSetItem('__TOKEN__', JSON.stringify(res.data.token))
              }
              catch (storageError) {
                console.error('降级存储也失败:', storageError)
              }
            }
            if (res.data.userId) {
              try {
                setUserName(res.data.userId)
              }
              catch {
                // userId 存储失败时使用降级方案
                try {
                  safeLocalStorageSetItem('__USER_NAME__', JSON.stringify(res.data.userId))
                }
                catch (storageError) {
                  console.error('userId 降级存储失败:', storageError)
                }
              }
            }
            // 确保 token 已写入 localStorage（useLocalStorageState 是同步的，但为了保险起见，使用微任务确保写入完成）
            await new Promise(resolve => setTimeout(resolve, 0))
            // 验证 token 是否真正写入，如果没有则使用降级方案
            const verifyToken = getTokenFromStorage()
            if (!verifyToken) {
              // 如果 useLocalStorageState 写入失败，使用安全函数再次尝试
              try {
                safeLocalStorageSetItem('__TOKEN__', JSON.stringify(res.data.token))
              }
              catch (storageError) {
                console.error('token 验证后降级存储失败:', storageError)
              }
            }
            // 主动触发 storage 事件，确保其他组件能监听到变化
            window.dispatchEvent(
              new StorageEvent('storage', {
                key: '__TOKEN__',
                oldValue: token,
                newValue: res.data.token,
                url: window.location.href,
                storageArea: localStorage,
              }),
            )
            // 确保 token 已写入 localStorage 后再调用业务接口
            const actualToken = getTokenFromStorage() || res.data.token
            if (actualToken && !hasCalledBusinessApis.current) {
              hasCalledBusinessApis.current = true
              // 触发自定义事件，通知 ChatEditor 强制重置为制度活化
              window.dispatchEvent(new CustomEvent('forceResetToGeneralMode'))
              const conversationId = await getSessionConversationId()
              dispatch(fetchConversations())
              // 2. 拉取常见问题等业务数据
              _handleToolClick(false, '', true, conversationId)
            }
          }
        }
        catch (error) {
          console.error('Guest 登录失败:', error)
          // 登录失败时清除标志，允许重试
          hasFetched.current = false
        }
      }
    }
  }, [setToken, setUserName, dispatch])

  // 监听路由参数变化，提取 userRoles（确保路由参数被正确解析）
  useEffect(() => {
    getUserRolesFromRoute()
  }, [location.search])

  useEffect(() => {
    login()
  }, []) // 依赖数组为空，只在组件挂载时执行一次

  useEffect(() => {
    // 只有登录成功（拿到 token）后才拉业务接口
    if (!token)
      return
    dispatch(clearCurrentToolId())
  }, [token, dispatch])

  // 监听路径变化，检测从收藏页面返回时刷新问题列表
  useEffect(() => {
    const currentPath = location.pathname
    const prevPath = prevPathRef.current

    console.log('[HomeNew] 路径变化检测 - 当前路径:', currentPath, '上一路径:', prevPath)
    // 检测从收藏页面返回到首页（避免首次挂载误触发）
    if (prevPath && prevPath !== currentPath && prevPath === '/collect' && (currentPath === '/' || currentPath === '/home')) {
      console.log('[HomeNew] 检测到从收藏页面返回 - 从 /collect 返回到首页')
      // 确保已登录后再调用接口
      if (token) {
        console.log('[HomeNew] 已登录，开始调用 handleRefreshQuestions')
        handleRefreshQuestions()
      }
      else {
        console.log('[HomeNew] 未登录，跳过刷新问题列表')
      }
    }

    // 更新上一次路径
    prevPathRef.current = currentPath
  }, [location.pathname, token, handleRefreshQuestions])

  return (
    <div className={styles.homePage}>
      {isLoading && (
        <div className="w-full h-full flex justify-center items-center">
          <SdreamLoading />
        </div>
      )}
      <div className="h-full w-full">
        <div className="box flex flex-col h-full w-full">
          <div className="flex-1 items-center pt-[24px] sm:pt-[32px] scrollbar-hide">
            <div className="w-full">
              <div className="flex justify-center gap-[20px]">
                {/* 左侧区域 - 产品问答和您可以试着问我 */}
                  <div
                    className="flex flex-col gap-[20px] items-center overflow-y-auto scrollbar-hide"
                    style={{ height: shouldChangeStyle ? 'calc(-64px + 100vh)' : '500px', background: shouldChangeStyle ? 'linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)' : '', borderRadius: '24px' }}
                  >
                  <motion.div className="w-full sm:w-auto" {...getAnimationProps(3)}>
                    <QuestionList
                      questions={otherQuestions.content}
                      dotColor="#CBECFF"
                      background="linear-gradient(180deg, #DEF6FF 0%, #FFFFFF 50%, #FFFFFF 100%)"
                      height={shouldChangeStyle ? '288px' : 'auto'}
                      title={otherQuestions.configName}
                      iconImg={HomeIcon2}
                      isToolBtn={shouldChangeStyle}
                      isLoaded={isDataLoaded}
                      onRefresh={handleRefreshQuestions}
                    />
                  </motion.div>
                  {shouldChangeStyle && (
                    <div className="w-full flex justify-center mt-auto pb-[24px]">
                      <img src={SmartIce} alt="Smart Ice" className="w-[260px] h-[218px] mt-[-12px] object-contain" />
                    </div>
                  )}
                  </div>
                {/* 右侧区域 */}
                <div className="hidden sm:flex flex-1 h-full">
                  <div
                    className="w-full h-full bg-transparent box-border rounded-[24px]"
                    style={{ height: 'calc(100vh - 64px)', background: '#FFFFFF', padding: '0 30px' }}
                  >
                    <Outlet />
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      </div>
    </div>
  )
}
