﻿<template>
  <van-button
    v-if="hasTransactions"
    :type="hasClassifiedResults ? 'success' : 'primary'"
    size="small"
    :loading="loading || saving"
    :disabled="loading || saving"
    @click="handleClick"
    class="smart-classify-btn"
  >
    <template v-if="!loading && !saving">
      <van-icon :name="hasClassifiedResults ? 'success' : 'fire'" />
      <span style="margin-left: 4px;">{{ hasClassifiedResults ? '保存分类' : '智能分类' }}</span>
    </template>
    <template v-else>
      {{ saving ? '保存中...' : '分类中...' }}
    </template>
  </van-button>
</template>

<script setup>
import { ref, computed } from 'vue'
import { showToast, closeToast } from 'vant'
import { smartClassify, batchUpdateClassify } from '@/api/transactionRecord'

const props = defineProps({
  transactions: {
    type: Array,
    default: () => []
  },
  onBeforeClassify: {
    type: Function,
    default: null
  }
})

const emit = defineEmits(['update', 'save', 'beforeClassify'])

const loading = ref(false)
const saving = ref(false)
const classifiedResults = ref([])
let toastInstance = null

const hasTransactions = computed(() => {
  return props.transactions && props.transactions.length > 0
})

const hasClassifiedResults = computed(() => {
  return classifiedResults.value.length > 0
})

/**
 * 点击按钮处理
 */
const handleClick = () => {
  if (hasClassifiedResults.value) {
    handleSaveClassify()
  } else {
    handleSmartClassify()
  }
}

/**
 * 保存分类结果
 */
const handleSaveClassify = async () => {
  try {
    saving.value = true
    showToast({
      message: '正在保存...',
      duration: 0,
      forbidClick: true,
      loadingType: 'spinner'
    })

    // 准备批量更新数据
    const items = classifiedResults.value.map(item => ({
      id: item.id,
      classify: item.classify,
      type: item.type
    }))

    const response = await batchUpdateClassify(items)
    
    closeToast()
    
    if (response.success) {
      showToast({
        type: 'success',
        message: `保存成功，已更新 ${items.length} 条记录`,
        duration: 2000
      })
      
      // 清空已分类结果
      classifiedResults.value = []
      
      // 通知父组件刷新数据
      emit('save')
    } else {
      showToast({
        type: 'fail',
        message: response.message || '保存失败',
        duration: 2000
      })
    }
  } catch (error) {
    console.error('保存分类失败:', error)
    closeToast()
    showToast({
      type: 'fail',
      message: '保存失败，请重试',
      duration: 2000
    })
  } finally {
    saving.value = false
  }
}

/**
 * 处理智能分类
 */
const handleSmartClassify = async () => {
  if (!props.transactions || props.transactions.length === 0) {
    showToast('没有可分类的交易记录')
    return
  }

  // 清空之前的分类结果
  classifiedResults.value = []
  
  const allTransactions = props.transactions
  const totalCount = allTransactions.length
  const batchSize = 30
  let processedCount = 0
  
  try {
    loading.value = true
    // 清除之前的Toast
    if (toastInstance) {
      closeToast()
    }

    // 等待父组件的 beforeClassify 事件处理完成（如果有返回 Promise） TODO 没有生效
    if (props.onBeforeClassify) {
      const shouldContinue = await props.onBeforeClassify()
      if (shouldContinue === false) {
        loading.value = false
        return
      }
    }

    toastInstance = showToast({
      message: '正在智能分类...',
      duration: 0,
      forbidClick: true,
      loadingType: 'spinner'
    })

    // 分批处理
    for (let i = 0; i < allTransactions.length; i += batchSize) {
      const batch = allTransactions.slice(i, i + batchSize)
      const transactionIds = batch.map(t => t.id)
      const currentBatch = Math.floor(i / batchSize) + 1
      const totalBatches = Math.ceil(allTransactions.length / batchSize)
      
      // 更新批次进度
      closeToast()
      toastInstance = showToast({
        message: `正在处理第 ${currentBatch}/${totalBatches} 批 (${i + 1}-${Math.min(i + batchSize, totalCount)} / ${totalCount})...`,
        duration: 0,
        forbidClick: true,
        loadingType: 'spinner'
      })

      const response = await smartClassify(transactionIds)
      
      if (!response.ok) {
        throw new Error('智能分类请求失败')
      }

      // 读取流式响应
      const reader = response.body.getReader()
      const decoder = new TextDecoder()
      let buffer = ''

      while (true) {
        const { done, value } = await reader.read()
        
        if (done) break
        
        buffer += decoder.decode(value, { stream: true })
        
        // 处理完整的事件（SSE格式：event: type\ndata: data\n\n）
        const events = buffer.split('\n\n')
        buffer = events.pop() || '' // 保留最后一个不完整的部分
        
        for (const eventBlock of events) {
          if (!eventBlock.trim()) continue
          
          try {
            const lines = eventBlock.split('\n')
            let eventType = ''
            let eventData = ''
            
            for (const line of lines) {
              if (line.startsWith('event: ')) {
                eventType = line.slice(7).trim()
              } else if (line.startsWith('data: ')) {
                eventData = line.slice(6).trim()
              }
            }
            
            if (eventType === 'start') {
              // 开始分类
              closeToast()
              toastInstance = showToast({
                message: `${eventData} (批次 ${currentBatch}/${totalBatches})`,
                duration: 0,
                forbidClick: true,
                loadingType: 'spinner'
              })
            } else if (eventType === 'data') {
              // 收到分类结果
              const data = JSON.parse(eventData)
              processedCount++
              
              // 记录分类结果
              classifiedResults.value.push({
                id: data.id,
                classify: data.Classify,
                type: data.Type
              })
              
              // 实时更新交易记录的分类信息
              const index = props.transactions.findIndex(t => t.id === data.id)
              if (index !== -1) {
                const transaction = props.transactions[index]
                transaction.upsetedClassify = data.Classify
                transaction.upsetedType = data.Type
              }
              
              // 更新进度
              closeToast()
              toastInstance = showToast({
                message: `已分类 ${processedCount}/${totalCount} 条 (批次 ${currentBatch}/${totalBatches})...`,
                duration: 0,
                forbidClick: true,
                loadingType: 'spinner'
              })
            } else if (eventType === 'end') {
              // 当前批次完成
              console.log(`批次 ${currentBatch}/${totalBatches} 完成`)
            } else if (eventType === 'error') {
              // 处理错误
              throw new Error(eventData || '分类失败')
            }
          } catch (e) {
            console.error('解析SSE事件失败:', e, eventBlock)
            throw e
          }
        }
      }
    }
    
    // 所有批次完成
    closeToast()
    toastInstance = null
    showToast({
      type: 'success',
      message: `分类完成，共处理 ${processedCount} 条记录，请点击"保存分类"按钮保存结果`,
      duration: 3000
    })
  } catch (error) {
    console.error('智能分类失败:', error)
    closeToast()
    toastInstance = null
    showToast({
      type: 'fail',
      message: '智能分类失败，请重试',
      duration: 2000
    })
  } finally {
    loading.value = false
    // 确保Toast被清除
    if (toastInstance) {
      setTimeout(() => {
        closeToast()
        toastInstance = null
      }, 100)
    }
  }
}

/**
 * 重置组件状态
 */
const reset = () => {
  classifiedResults.value = []
  loading.value = false
  saving.value = false
}

defineExpose({
  reset
});

</script>

<style scoped>
.smart-classify-btn {
  display: inline-flex;
  align-items: center;
  white-space: nowrap;
  border-radius: 16px;
  padding: 6px 12px;
}
</style>
