import { defineStore } from 'pinia'
import { ServeFindFileSplitInfo, ServeFileSubareaUpload } from '@/api/upload'
import { ServeSendTalkFile } from '@/api/chat'
import { uploadImg } from '@/api/upload'
import {
  useDialogueStore
} from '@/store'
// @ts-ignore
const message = window.$message

// 定义上传项接口
interface UploadItem {
  file: File;
  talk_type: number;
  receiver_id: number;
  upload_id: string;
  client_upload_id?: string; // 上传时的客户端ID
  uploadIndex: number;
  percentage: number;
  status: number; // 文件上传状态 0:等待上传 1:上传中 2:上传完成 3:网络异常
  files: FormData[];
  avatar: string;
  username: string;
  is_paused?: boolean; // 是否暂停上传
  form?: FormData;
  progress_interval?: any;
  upload_controller?: AbortController;
  onProgress?: (percentage: number) => void;
  onComplete?: (data: any) => void;
}

// 处理拆分上传文件
function fileSlice(file: File, uploadId: string, eachSize: number) {
  const splitNum = Math.ceil(file.size / eachSize) // 分片总数
  const items: FormData[] = []

  // 处理每个分片的上传操作
  for (let i = 0; i < splitNum; i++) {
    const start = i * eachSize
    const end = Math.min(file.size, start + eachSize)

    const form = new FormData()
    form.append('file', file.slice(start, end))
    form.append('upload_id', uploadId)
    form.append('split_index', `${i + 1}`)
    form.append('split_num', `${splitNum}`)

    items.push(form)
  }

  return items
}

export const useUploadsStore = defineStore('uploads', {
  state: () => {
    return {
      isShow: false,
      items: [] as UploadItem[],
      dialogueStore: useDialogueStore()
    }
  },
  getters: {
    successCount: (state) => {
      return state.items.filter((item: any) => {
        return item.status === 2
      }).length
    }
  },
  actions: {
    close() {
      this.isShow = false
    },
    // 获取分片文件数组索引
    findItem(uploadId: string): UploadItem | undefined {
      return this.items.find((item) => item.upload_id === uploadId)
    },

    // 通过客户端ID查找上传项
    findItemByClientId(clientUploadId: string): UploadItem | undefined {
      return this.items.find((item) => item.client_upload_id === clientUploadId)
    },

    // // 暂停文件上传
    // pauseUpload(uploadId: string) {
    //   const item = this.findItem(uploadId)
    //   if (!item) return
      
    //   item.is_paused = true
    //   console.log(`暂停上传: ${uploadId}`)
    // },

    // 恢复文件上传
    // resumeUpload(uploadId: string) {
    //   const item = this.findItem(uploadId)
    //   if (!item) return
      
    //   item.is_paused = false
    //   console.log(`恢复上传: ${uploadId}`)
      
    //   // 继续上传
    //   this.triggerUpload(uploadId)
    // },

    // 发送上传消息
    async sendUploadMessage(item: any) {
      try {
        await ServeSendTalkFile({
          upload_id: item.upload_id,
          receiver_id: item.receiver_id,
          talk_type: item.talk_type
        })
      } catch (error) {
        console.error("发送上传消息失败:", error)
      }
    },

    // 初始化上传（使用分片上传方式）
    async initUploadFile(
      file: File, 
      talkType: number, 
      receiverId: number, 
      username: string,
      uploadId: string,
      onProgress: (percentage: number) => void,
      onComplete: (data: any) => void
    ) {
      // 使用分片上传机制，先获取分片信息
      try {
        const res = await ServeFindFileSplitInfo({
          file_name: file.name,
          file_size: file.size
        })
        
        if (res.code == 200) {
          const { upload_id, split_size } = res.data
          
          // 使用较小的分片大小，以获得更细粒度的进度控制
          // 将分片大小减半，增加分片数量
          const actualSplitSize = Math.min(split_size, 512 * 1024); // 使用更小的分片，如512KB
          
          // 创建分片数组
          const fileChunks = fileSlice(file, upload_id, actualSplitSize)
          
          // @ts-ignore
          this.items.unshift({
            file: file,
            talk_type: talkType,
            receiver_id: receiverId,
            upload_id: upload_id,
            client_upload_id: uploadId, // 客户端生成的上传ID，用于前端标识
            uploadIndex: 0,
            percentage: 0,
            status: 0, // 文件上传状态 0:等待上传 1:上传中 2:上传完成 3:网络异常
            files: fileChunks,
            avatar: '',
            username: username,
            is_paused: false,
            onProgress: onProgress,
            onComplete: onComplete,
          })
          
          this.isShow = false // 不显示上传管理抽屉
          
          // 开始上传分片
          this.triggerUpload(upload_id, uploadId)
        } else {
          message.error(res.message)
          onProgress(-1) // 通知上传失败
        }
      } catch (error) {
        console.error("初始化分片上传失败:", error);
        message.error("初始化上传失败，请重试")
        onProgress(-1)
      }
    },
    
    // 触发分片上传
    async triggerUpload(uploadId: string, clientUploadId?: string) {
      const currentItem = this.findItem(uploadId)
      if (!currentItem) return
      
      // 如果已暂停，不继续上传
      if (currentItem.is_paused) return
      
      // 如果已上传完成，不继续上传
      if (currentItem.uploadIndex >= currentItem.files.length) {
        if (clientUploadId) {
          this.completeUpload(currentItem, clientUploadId)
        }
        return
      }
      
      // 获取当前要上传的分片
      const form = currentItem.files[currentItem.uploadIndex]
      
      // 更新状态为上传中
      currentItem.status = 1
      
      // 上传当前分片
      try {
        const res = await ServeFileSubareaUpload(form)
        
        // 获取最新的项目状态，确保仍然存在且没有被暂停
        const updatedItem = this.findItem(uploadId)
        if (!updatedItem || updatedItem.is_paused) return
        
        if (res.code == 200) {
          // 当前分片上传成功，增加索引
          updatedItem.uploadIndex++
          
          // 计算上传进度
          const percentage = (updatedItem.uploadIndex / updatedItem.files.length) * 100
          updatedItem.percentage = parseFloat(percentage.toFixed(1))
          
          // 回调进度
          if (updatedItem.onProgress) {
            updatedItem.onProgress(updatedItem.percentage)
          }
          // if (clientUploadId) {
          //   this.dialogueStore.updateUploadProgress(clientUploadId, percentage)
          // }
          // 检查是否全部上传完成
          if (updatedItem.uploadIndex === updatedItem.files.length) {
            // 所有分片上传完成
            if (clientUploadId) {
              this.completeUpload(updatedItem, clientUploadId)
            }
          } else {
            // 继续上传下一个分片
            this.triggerUpload(uploadId, clientUploadId)
          }
        } else {
          // 上传失败处理
          console.error(`分片上传失败，错误码: ${res.code}，错误信息: ${res.message || '未知错误'}`);
          updatedItem.status = 3
          
          // 尝试重试当前分片
          this.retryUpload(uploadId, clientUploadId, res.message || '上传失败，请重试')
        }
      } catch (error) {
        console.error("分片上传错误:", error);
        
        // 获取最新的项目状态
        const updatedItem = this.findItem(uploadId)
        if (!updatedItem) return
        
        // 如果是暂停导致的错误，不改变状态
        if (updatedItem.is_paused) return
        
        updatedItem.status = 3
        
        // 尝试重试当前分片
        this.retryUpload(uploadId, clientUploadId, '网络错误，正在重试')
      }
    },
    
    // 重试上传
    retryUpload(uploadId: string, clientUploadId?: string, errorMessage?: string) {
      const item = this.findItem(uploadId)
      if (!item) return
      
      // 如果有暂停/恢复按钮，先告知用户上传出错
      if (item.onProgress) {
        item.onProgress(-1)
      }
      
      // 显示错误提示
      message.warning(errorMessage)
      
      // 创建一个5秒后自动重试的机制
      setTimeout(() => {
        const currentItem = this.findItem(uploadId)
        if (!currentItem) return
        
        // 如果用户没有手动暂停，则自动重试
        if (!currentItem.is_paused) {
          console.log('正在重试上传分片...');
          this.triggerUpload(uploadId, clientUploadId)
        }
      }, 5000)
    },
    
    // 完成上传
    async completeUpload(item: UploadItem, clientUploadId: string) {
      if (!item) return;
      
      item.status = 2
      item.percentage = 100
      if (item.onProgress) {
        item.onProgress(100)
      }
      
      // 获取最终URL并回调
      try {
        await ServeSendTalkFile({
          upload_id: item.upload_id,
          receiver_id: item.receiver_id,
          talk_type: item.talk_type
        })
        
        if (item.onComplete) {
          item.onComplete(item)
        }
      } catch (error) {
        console.error("发送文件消息失败:", error);
      }
    },
    
    
    pauseUpload(clientUploadId: string) {
      const item = this.findItemByClientId(clientUploadId)
      if (!item) return
      
      item.is_paused = true
    },
    
    // 恢复上传
    resumeUpload(clientUploadId: string) {
      const item = this.findItemByClientId(clientUploadId)
      if (!item) return
      
      item.is_paused = false
      
      // 继续上传
      if (item.upload_id) {
        this.triggerUpload(item.upload_id, clientUploadId)
      }
    },
    
    // 重试文件上传
    retryCommonUpload(uploadId: string, errorMessage: string) {
      const item = this.findItem(uploadId)
      if (!item) return
      
      // 显示错误提示
      message.warning(errorMessage)
      
      // 创建一个5秒后自动重试的机制
      setTimeout(() => {
        const currentItem = this.findItem(uploadId)
        if (!currentItem) return
        
        // 如果用户没有手动暂停，则自动重试
        if (!currentItem.is_paused) {
          console.log('正在重试上传分片...');
          this.triggerUpload(uploadId)
        }
      }, 5000)
    },
  }
})
