import { useMemo, useCallback } from 'react'
import { request } from '@/http/request'
import type { TaskArtifact } from '../types'
import type { PlatformConfig } from './useNovaEvents'

export interface ConversationInfo {
  conversation_id: string
  title?: string
  task_status?: string
  is_read?: boolean
  is_favourite?: boolean
}

interface UseNovaServiceProps {
  platformConfig?: PlatformConfig
  getToken?: () => string | undefined
  getTenantId?: () => string | undefined
  conversationId?: string
}

interface DirFileItem {
  desc?: string
  file_name?: string
  file_type?: string
  last_modified?: number
  path?: string
}

const toAbsoluteHttpUrl = (value: unknown): string | null => {
  if (typeof value !== 'string' || !value) return null
  if (value.startsWith('http://') || value.startsWith('https://')) return value
  return null
}

const extractDirFileList = (payload: unknown): DirFileItem[] => {
  if (Array.isArray(payload)) return payload
  if (!payload || typeof payload !== 'object') return []
  const obj = payload as Record<string, unknown>
  if (Array.isArray(obj.data)) return obj.data as DirFileItem[]
  return []
}

const normalizeFileName = (name: string): string => {
  const raw = name.trim()
  if (!raw) return ''
  const withoutPrefix = raw.startsWith('/upload/') ? raw.slice('/upload/'.length) : raw
  return withoutPrefix
}

const resolvePathByName = (files: DirFileItem[], fileName?: string): string | null => {
  if (!fileName) return null
  const normalizedName = normalizeFileName(fileName)
  if (!normalizedName) return null

  const expectedSegment = `upload/${normalizedName}`
  const matched = files.find(item => {
    if (typeof item.file_name !== 'string' || !item.file_name) return false
    return item.file_name.includes(expectedSegment)
  })

  return matched?.path || null
}

export function useNovaService({
  platformConfig,
  conversationId,
}: UseNovaServiceProps) {
  // API Client Singleton
  const apiClient = useMemo(() => {
    if (!platformConfig?.apiBaseUrl) {
      return null
    }

    return request
  }, [platformConfig])

  // Get Artifact URL Method
  const getArtifactUrl = useCallback(
    async (
      artifact: TaskArtifact,
      params?: Record<string, string>
    ): Promise<{ data: string }> => {
      try {
        if (!apiClient) {
          throw new Error('API client is not initialized')
        }

        const taskId = artifact.task_id || conversationId
        let resolvedPath = artifact.path

        if (taskId) {
          const dirFilesResponse = await apiClient.post<unknown>(
            '/v1/super_agent/chat/get_dir_file',
            { task_id: taskId }
          )
          const dirFiles = extractDirFileList(dirFilesResponse)
          const matchedPath = resolvePathByName(dirFiles, artifact.file_name)
          if (matchedPath) {
            resolvedPath = matchedPath
          }
        }

        // Call OSS URL interface
        const response = await apiClient.post<string>('/chat/oss_url', {
          file_path: resolvedPath,
          task_id: taskId,
          params
        })
        const signedUrl = toAbsoluteHttpUrl(response) || ''
        const fallback = toAbsoluteHttpUrl(artifact.path) || ''
        return { data: signedUrl || fallback }
      } catch (error) {
        console.error('Failed to fetch artifact URL:', error)
        return { data: toAbsoluteHttpUrl(artifact.path) || '' }
      } 
    },
    [conversationId, apiClient]
  )

  const stopChat = useCallback(async () => {
    try {
      if (!apiClient) {
        throw new Error('API client is not initialized')
      }

      if (!conversationId) {
        throw new Error('Conversation ID is required')
      }

      await apiClient.get('/chat/stop', { conversation_id: conversationId })
    } catch (error) {
      console.error('Failed to stop chat:', error)
      throw error
    }
  }, [conversationId, apiClient])

  /** 获取会话信息列表（用于轮询 task_status），使用 novaRequest */
  const getConversationInfoList = useCallback(
    async (conversationIds: string[]) => {
      if (conversationIds.length === 0) {
        return { data: [] as ConversationInfo[] }
      }
      const res = await request.post<{ data?: ConversationInfo[] } | ConversationInfo[]>(
        '/conversation/info',
        {  conversation_ids: conversationIds } 
      )
      const list = Array.isArray(res) ? res : (res?.data ?? [])
      return { data: list }
    },
    []
  )

  return {
    apiClient,
    getArtifactUrl,
    stopChat,
    getConversationInfoList,
  }
}
