
import { useCallback, useRef, useMemo } from 'react'
import type { UploadFile } from '../types'
import { request } from '@/http/request'
import { createCustomOSSUploader } from '@bty/uploader'
import { getSTSToken, getOssSignatureUrl } from '@apis/oss'

// Simple helper to mimic MIME type detection
export const ACCEPT_FILE_TYPE_LIST = [
  '.pdf', '.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx',
  '.txt', '.json', '.csv', '.md',
  '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp', '.svg', '.ico',
  '.html', '.py', '.jsonld', '.xml', '.zip',
  '.mp3', '.mp4', '.mov', '.m4a',
  '.pdb', '.mermaid',
]

export function getMimeByAcceptList(filename: string): string | undefined {
  const ext = `.${(filename.split('.').pop() || '').toLowerCase()}`
  const map: Record<string, string> = {
    '.pdf': 'application/pdf',
    '.doc': 'application/msword',
    '.docx': 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
    '.xls': 'application/vnd.ms-excel',
    '.xlsx': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    '.ppt': 'application/vnd.ms-powerpoint',
    '.pptx': 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
    '.txt': 'text/plain',
    '.json': 'application/json',
    '.csv': 'text/csv',
    '.md': 'text/markdown',
    '.png': 'image/png',
    '.jpg': 'image/jpeg',
    '.jpeg': 'image/jpeg',
    '.gif': 'image/gif',
    '.bmp': 'image/bmp',
    '.webp': 'image/webp',
    '.svg': 'image/svg+xml',
    '.ico': 'image/x-icon',
    '.html': 'text/html',
    '.jsonld': 'application/ld+json',
    '.pdb': 'application/vnd.microsoft.portable-executable',
    '.mermaid': 'text/mermaid',
  }
  return map[ext] || undefined
}

export interface UseFileUploaderProps {
  onUploadStart?: (file: UploadFile) => void
  onUploadEnd?: (file: UploadFile) => void
  onUploadError?: (error: Error, file?: UploadFile) => void
  onFileUpdate?: (file: UploadFile) => void
}

export function useFileUploader({
  onUploadStart,
  onUploadEnd,
  onUploadError,
  onFileUpdate,
}: UseFileUploaderProps = {}) {
  const uploadUUId = useRef<string>('')
  
  // Initialize OSS Uploader with STS token provider from our local package
  const ossUploader = useMemo(() => {
    return createCustomOSSUploader(getSTSToken)
  }, [])

  const uploadFile = useCallback(async (file: File) => {
    // 1. Validation
    const isValidSize = file.size <= 100 * 1024 * 1024 // 100MB
    if (!isValidSize) {
      console.warn('File size exceeds 100MB limit')
      return
    }
    
    // 2. Init file object and State
    const uid = crypto.randomUUID()
    const mimeType = getMimeByAcceptList(file.name) || file.type || 'application/octet-stream'
    
    const tempFile: UploadFile = {
      uid,
      name: file.name,
      type: mimeType,
      byte_size: file.size,
      uploadStatus: 'pending',
      progress: 0,
      url: URL.createObjectURL(file),
    }

    onUploadStart?.(tempFile)
    
    try {
      // 3. Construct File Path (Business Logic)
      const timestamp = new Date().valueOf()
      const uuid = crypto.randomUUID()
      uploadUUId.current = uuid
      const filePath = `super_agent/user_upload_file/${uuid}/_${timestamp}_${file.name}`

      // 4. Upload to OSS using the shared package
      await ossUploader.multipartUpload({
        filePath,
        file,
        options: {
          headers: {
            'Content-Type': mimeType,
            'Content-Disposition': 'inline',
          },
          progress: (progress: number) => {
             // OSS SDK returns progress as 0-1
             onFileUpdate?.({
               ...tempFile,
               progress: Math.floor(progress * 100),
               uploadStatus: 'uploading'
             })
          }
        },
      })

      // 5. Get Signature URL (Optional / if private)
      const signatureUrl = await getOssSignatureUrl(filePath)

      // 6. Create File Upload Record (Backend Sync)
      const lastDotIndex = file.name.lastIndexOf('.')
      const splitName = lastDotIndex !== -1
        ? [file.name.substring(0, lastDotIndex), file.name.substring(lastDotIndex + 1)]
        : [file.name]
      
      const safeName = `${splitName[0]}-${Math.random().toString(36).substring(2, 5)}${splitName.length > 1 ? `.${splitName[1]}` : ''}`
      
      const res = await request.post<{ file_upload_record_id: string }>('/file/record', {
        file_url: filePath,
        file_type: file.type || 'application/octet-stream',
        file_name: safeName,
        file_byte_size: file.size || 0,
        conversation_id: uuid,
      })

      // 7. Finalize
      const finalFile: UploadFile = {
        ...tempFile,
        name: safeName, 
        url: signatureUrl,
        upload_file_id: res.file_upload_record_id,
        progress: 100,
        uploadStatus: 'success',
      }
      
      onFileUpdate?.(finalFile)
      onUploadEnd?.(finalFile)

    } catch (error) {
      console.error('Upload failed:', error)
      const errorFile: UploadFile = {
        ...tempFile,
        uploadStatus: 'error'
      }
      onFileUpdate?.(errorFile)
      onUploadError?.(error as Error, errorFile)
    }
  }, [ossUploader, onUploadStart, onUploadEnd, onUploadError, onFileUpdate])

  return {
    uploadFile,
    accept: ACCEPT_FILE_TYPE_LIST.join(','),
  }
}
