import { defineStore } from 'pinia'
import { jobsAPI, filesAPI } from '@/services/jobs'
import { ElMessage, ElNotification } from 'element-plus'
import { saveAs } from 'file-saver'

export const useJobsStore = defineStore('jobs', {
  state: () => ({
    jobs: [],
    currentJob: null,
    pagination: {
      page: 1,
      per_page: 20,
      total: 0,
      pages: 0
    },
    loading: false,
    uploadProgress: 0,
    filters: {
      status: 'all',
      search: ''
    },
    // 輪詢管理
    pollingIntervals: new Map() // 存儲每個任務的輪詢間隔 ID
  }),
  
  getters: {
    // 按狀態分組的任務
    pendingJobs: (state) => state.jobs.filter(job => job.status === 'PENDING'),
    processingJobs: (state) => state.jobs.filter(job => job.status === 'PROCESSING'),
    completedJobs: (state) => state.jobs.filter(job => job.status === 'COMPLETED'),
    failedJobs: (state) => state.jobs.filter(job => job.status === 'FAILED'),
    retryJobs: (state) => state.jobs.filter(job => job.status === 'RETRY'),
    
    // 根據 UUID 查找任務
    getJobByUuid: (state) => (uuid) => {
      return state.jobs.find(job => job.job_uuid === uuid)
    },
    
    // 統計資訊
    jobStats: (state) => ({
      total: state.jobs.length,
      pending: state.jobs.filter(job => job.status === 'PENDING').length,
      processing: state.jobs.filter(job => job.status === 'PROCESSING').length,
      completed: state.jobs.filter(job => job.status === 'COMPLETED').length,
      failed: state.jobs.filter(job => job.status === 'FAILED').length
    })
  },
  
  actions: {
    /**
     * 取得任務列表
     * @param {Object} options - 查詢選項
     */
    async fetchJobs(options = {}) {
      try {
        this.loading = true
        
        const params = {
          page: options.page || this.pagination.page,
          per_page: options.per_page || this.pagination.per_page,
          status: options.status || this.filters.status
        }
        
        const response = await jobsAPI.getJobs(params)
        
        if (response.success) {
          this.jobs = response.data.jobs
          this.pagination = response.data.pagination
          return response.data
        }
      } catch (error) {
        console.error('取得任務列表失敗:', error)
        ElMessage.error('載入任務列表失敗')
      } finally {
        this.loading = false
      }
    },
    
    /**
     * 上傳檔案
     * @param {FormData} formData - 表單資料
     * @param {Function} onProgress - 進度回調
     */
    async uploadFile(formData, onProgress) {
      try {
        this.uploadProgress = 0
        
        // 設定進度回調
        if (onProgress) {
          formData.onUploadProgress = (progressEvent) => {
            const progress = Math.round((progressEvent.loaded * 100) / progressEvent.total)
            this.uploadProgress = progress
            onProgress(progress)
          }
        }
        
        const response = await jobsAPI.uploadFile(formData)
        
        if (response.success) {
          // 將新任務添加到列表頂部
          const newJob = response.data
          this.jobs.unshift(newJob)
          
          ElMessage.success('檔案上傳成功，已加入翻譯佇列')
          return newJob
        }
      } catch (error) {
        console.error('檔案上傳失敗:', error)
        throw error
      } finally {
        this.uploadProgress = 0
      }
    },
    
    /**
     * 取得任務詳情
     * @param {string} jobUuid - 任務 UUID
     */
    async fetchJobDetail(jobUuid) {
      try {
        const response = await jobsAPI.getJobDetail(jobUuid)
        
        if (response.success) {
          this.currentJob = response.data
          return response.data
        }
      } catch (error) {
        console.error('取得任務詳情失敗:', error)
        ElMessage.error('載入任務詳情失敗')
      }
    },
    
    /**
     * 重試失敗任務
     * @param {string} jobUuid - 任務 UUID
     */
    async retryJob(jobUuid) {
      try {
        const response = await jobsAPI.retryJob(jobUuid)
        
        if (response.success) {
          // 更新本地任務狀態
          const jobIndex = this.jobs.findIndex(job => job.job_uuid === jobUuid)
          if (jobIndex !== -1) {
            this.jobs[jobIndex] = { ...this.jobs[jobIndex], ...response.data }
          }
          
          ElMessage.success('任務已重新加入佇列')
          return response.data
        }
      } catch (error) {
        console.error('重試任務失敗:', error)
        ElMessage.error('重試任務失敗')
      }
    },
    
    /**
     * 取消任務
     * @param {string} jobUuid - 任務 UUID
     */
    async cancelJob(jobUuid) {
      try {
        const response = await jobsAPI.cancelJob(jobUuid)
        
        if (response.success) {
          const jobIndex = this.jobs.findIndex(job => job.job_uuid === jobUuid)
          if (jobIndex !== -1) {
            this.jobs[jobIndex] = { ...this.jobs[jobIndex], status: 'CANCELLED' }
          }
          
          ElMessage.success('任務已取消')
        }
      } catch (error) {
        console.error('取消任務失敗:', error)
        ElMessage.error('取消任務失敗')
      }
    },
    
    /**
     * 刪除任務
     * @param {string} jobUuid - 任務 UUID
     */
    async deleteJob(jobUuid) {
      try {
        const response = await jobsAPI.deleteJob(jobUuid)
        
        if (response.success) {
          // 先停止輪詢
          this.unsubscribeFromJobUpdates(jobUuid)
          
          // 從列表中移除任務
          const jobIndex = this.jobs.findIndex(job => job.job_uuid === jobUuid)
          if (jobIndex !== -1) {
            this.jobs.splice(jobIndex, 1)
          }
          
          ElMessage.success('任務已刪除')
        }
      } catch (error) {
        console.error('刪除任務失敗:', error)
        ElMessage.error('刪除任務失敗')
      }
    },
    
    /**
     * 下載檔案
     * @param {string} jobUuid - 任務 UUID
     * @param {string} languageCode - 語言代碼
     * @param {string} filename - 檔案名稱
     */
    async downloadFile(jobUuid, languageCode, filename) {
      try {
        const response = await filesAPI.downloadFile(jobUuid, languageCode)
        
        // 使用 FileSaver.js 下載檔案
        const blob = new Blob([response], { type: 'application/octet-stream' })
        saveAs(blob, filename)
        
        ElMessage.success('檔案下載完成')
      } catch (error) {
        console.error('下載檔案失敗:', error)
        ElMessage.error('檔案下載失敗')
      }
    },
    
    /**
     * 批量下載檔案
     * @param {string} jobUuid - 任務 UUID
     * @param {string} filename - 壓縮檔名稱
     */
    async downloadAllFiles(jobUuid, filename) {
      try {
        const response = await filesAPI.downloadAllFiles(jobUuid)
        
        const blob = new Blob([response], { type: 'application/zip' })
        saveAs(blob, filename || `${jobUuid}.zip`)
        
        ElMessage.success('檔案打包下載完成')
      } catch (error) {
        console.error('批量下載失敗:', error)
        ElMessage.error('批量下載失敗')
      }
    },
    
    /**
     * 更新任務狀態（用於 WebSocket 即時更新）
     * @param {string} jobUuid - 任務 UUID
     * @param {Object} statusUpdate - 狀態更新資料
     */
    updateJobStatus(jobUuid, statusUpdate) {
      const jobIndex = this.jobs.findIndex(job => job.job_uuid === jobUuid)
      
      if (jobIndex !== -1) {
        this.jobs[jobIndex] = { ...this.jobs[jobIndex], ...statusUpdate }
        
        // 如果是當前查看的任務詳情，也要更新
        if (this.currentJob && this.currentJob.job_uuid === jobUuid) {
          this.currentJob = { ...this.currentJob, ...statusUpdate }
        }
        
        // 任務完成時顯示通知
        if (statusUpdate.status === 'COMPLETED') {
          ElNotification({
            title: '翻譯完成',
            message: `檔案「${this.jobs[jobIndex].original_filename}」翻譯完成`,
            type: 'success',
            duration: 5000
          })
        } else if (statusUpdate.status === 'FAILED') {
          ElNotification({
            title: '翻譯失敗',
            message: `檔案「${this.jobs[jobIndex].original_filename}」翻譯失敗`,
            type: 'error',
            duration: 5000
          })
        }
      }
    },
    
    /**
     * 設定篩選條件
     * @param {Object} filters - 篩選條件
     */
    setFilters(filters) {
      this.filters = { ...this.filters, ...filters }
    },
    
    /**
     * 訂閱任務更新 (輪詢機制)
     * @param {string} jobUuid - 任務 UUID
     */
    subscribeToJobUpdates(jobUuid) {
      // 如果已經在輪詢這個任務，先停止舊的輪詢
      if (this.pollingIntervals.has(jobUuid)) {
        this.unsubscribeFromJobUpdates(jobUuid)
      }

      console.log(`[DEBUG] 開始訂閱任務更新: ${jobUuid}`)
      
      const pollInterval = setInterval(async () => {
        try {
          const job = await this.fetchJobDetail(jobUuid)
          
          if (job) {
            // 任務存在，更新本地狀態
            const existingJobIndex = this.jobs.findIndex(j => j.job_uuid === jobUuid)
            if (existingJobIndex !== -1) {
              // 更新現有任務
              this.jobs[existingJobIndex] = { ...this.jobs[existingJobIndex], ...job }
            }
            
            // 檢查任務是否已完成
            if (['COMPLETED', 'FAILED'].includes(job.status)) {
              console.log(`[DEBUG] 任務 ${jobUuid} 已完成 (${job.status})，停止輪詢`)
              this.unsubscribeFromJobUpdates(jobUuid)
              
              // 顯示完成通知
              if (job.status === 'COMPLETED') {
                ElNotification({
                  title: '翻譯完成',
                  message: `檔案 "${job.original_filename}" 翻譯完成`,
                  type: 'success',
                  duration: 5000
                })
              }
            }
          } else {
            // 任務不存在（可能被刪除），停止輪詢
            console.log(`[DEBUG] 任務 ${jobUuid} 不存在，停止輪詢`)
            this.unsubscribeFromJobUpdates(jobUuid)
            
            // 從本地列表中移除任務
            const existingJobIndex = this.jobs.findIndex(j => j.job_uuid === jobUuid)
            if (existingJobIndex !== -1) {
              this.jobs.splice(existingJobIndex, 1)
            }
          }
        } catch (error) {
          console.error(`輪詢任務 ${jobUuid} 狀態失敗:`, error)
          
          // 檢查是否是 404 錯誤（任務不存在）
          if (error.response?.status === 404) {
            console.log(`[DEBUG] 任務 ${jobUuid} 已被刪除，停止輪詢`)
            this.unsubscribeFromJobUpdates(jobUuid)
            
            // 從本地列表中移除任務
            const existingJobIndex = this.jobs.findIndex(j => j.job_uuid === jobUuid)
            if (existingJobIndex !== -1) {
              this.jobs.splice(existingJobIndex, 1)
            }
          } else {
            // 其他錯誤，繼續輪詢但記錄錯誤
            console.warn(`輪詢任務 ${jobUuid} 時發生錯誤，將繼續重試:`, error.message)
          }
        }
      }, 3000) // 每 3 秒檢查一次
      
      // 儲存輪詢間隔 ID
      this.pollingIntervals.set(jobUuid, pollInterval)
    },
    
    /**
     * 取消訂閱任務更新
     * @param {string} jobUuid - 任務 UUID  
     */
    unsubscribeFromJobUpdates(jobUuid) {
      const intervalId = this.pollingIntervals.get(jobUuid)
      if (intervalId) {
        clearInterval(intervalId)
        this.pollingIntervals.delete(jobUuid)
        console.log(`[DEBUG] 已取消任務 ${jobUuid} 的輪詢訂閱`)
      }
    },
    
    /**
     * 停止所有輪詢
     */
    stopAllPolling() {
      for (const [jobUuid, intervalId] of this.pollingIntervals) {
        clearInterval(intervalId)
        console.log(`[DEBUG] 已停止任務 ${jobUuid} 的輪詢`)
      }
      this.pollingIntervals.clear()
    },

    /**
     * 重置任務列表
     */
    resetJobs() {
      // 先停止所有輪詢
      this.stopAllPolling()
      
      this.jobs = []
      this.currentJob = null
      this.pagination = {
        page: 1,
        per_page: 20,
        total: 0,
        pages: 0
      }
    }
  }
})