﻿<template>
  <div class="page-container-flex smart-classification">
    <van-nav-bar
      title="智能分类"
      left-text="返回"
      left-arrow
      @click-left="onClickLeft"
    />

    <div
      class="scroll-content"
      style="padding-top: 5px"
    >
      <!-- 统计信息 -->
      <div class="stats-info">
        <span class="stats-label">未分类账单 </span>
        <span class="stats-value">{{ unclassifiedCount }} 条，共计 {{ totalGroups }} 组</span>
      </div>

      <!-- 分组列表组件 -->
      <ReasonGroupList
        ref="groupListRef"
        :selectable="true"
        @data-loaded="handleDataLoaded"
        @data-changed="handleDataChanged"
      />

      <!-- 底部安全距离 -->
      <div style="height: calc(50px + env(safe-area-inset-bottom, 0px))" />
    </div>

    <!-- 底部操作按钮 -->
    <div class="bottom-button">
      <van-button
        type="primary"
        :loading="classifying"
        :disabled="selectedCount === 0"
        round
        class="action-btn"
        @click="startClassify"
      >
        {{ classifying ? '分类中...' : `开始分类 (${selectedCount}组)` }}
      </van-button>

      <van-button
        type="success"
        :disabled="!hasChanges || classifying"
        round
        class="action-btn"
        @click="saveClassifications"
      >
        保存分类
      </van-button>
    </div>
  </div>
</template>

<script setup>
import { ref, computed, onMounted, nextTick } from 'vue'
import { useRouter } from 'vue-router'
import { showToast, showLoadingToast, closeToast, showConfirmDialog } from 'vant'
import { getUnclassifiedCount, smartClassify, batchUpdateClassify } from '@/api/transactionRecord'
import ReasonGroupList from '@/components/ReasonGroupList.vue'

const router = useRouter()
const groupListRef = ref(null)
const unclassifiedCount = ref(0)
const totalGroups = ref(0)
const classifying = ref(false)
const hasChanges = ref(false)
const classifyBuffer = ref('')
const suppressDataChanged = ref(false)

// 计算已选中的数量
const selectedCount = computed(() => {
  if (!groupListRef.value) {
    return 0
  }
  return groupListRef.value.getSelectedReasons().size
})

// 加载未分类账单数量
const loadUnclassifiedCount = async () => {
  try {
    const res = await getUnclassifiedCount()
    if (res.success) {
      unclassifiedCount.value = res.data
    }
  } catch (error) {
    console.error('获取未分类数量失败', error)
  }
}

// 处理数据加载完成
const handleDataLoaded = ({ total }) => {
  totalGroups.value = total
  // 默认全选所有分组
  if (groupListRef.value) {
    groupListRef.value.selectAll()
  }
}

// 处理数据变更
const handleDataChanged = async () => {
  if (suppressDataChanged.value) {
    suppressDataChanged.value = false
    return
  }

  await loadUnclassifiedCount()
  hasChanges.value = false
}

const onClickLeft = () => {
  if (hasChanges.value) {
    showConfirmDialog({
      title: '提示',
      message: '有未保存的分类结果，确定要离开吗？'
    })
      .then(() => {
        if (window.history.length > 1) {
          router.back()
        } else {
          router.replace('/')
        }
      })
      .catch(() => {})
  } else {
    if (window.history.length > 1) {
      router.back()
    } else {
      router.replace('/')
    }
  }
}

// 开始智能分类
const startClassify = async () => {
  if (!groupListRef.value) {
    return
  }

  // 获取所有选中分组
  const selectedGroups = groupListRef.value.getList(true)

  // 获取所有选中分组的账单ID
  const idsToClassify = []
  for (const group of selectedGroups) {
    idsToClassify.push(...group.transactionIds)
  }

  if (idsToClassify.length === 0) {
    showToast('请先选择要分类的账单组')
    return
  }

  showLoadingToast({
    message: '智能分类中...',
    forbidClick: true,
    duration: 0
  })

  classifying.value = true
  classifyBuffer.value = ''

  // 用于存储分类结果的临时对象
  const classifyResults = new Map()

  try {
    const response = await smartClassify(idsToClassify)

    if (!response.ok) {
      throw new Error(`HTTP error! status: ${response.status}`)
    }

    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 })
      const lines = buffer.split('\n\n')
      buffer = lines.pop() || ''

      for (const line of lines) {
        if (!line.trim()) {
          continue
        }

        const eventMatch = line.match(/^event: (.+)$/m)
        const dataMatch = line.match(/^data: (.+)$/m)

        if (eventMatch && dataMatch) {
          const eventType = eventMatch[1]
          const data = dataMatch[1]

          handleSSEEvent(eventType, data, classifyResults)
        }
      }
    }
  } catch (error) {
    console.error('智能分类失败', error)
    showToast(`分类失败: ${error.message}`)
  } finally {
    classifying.value = false
    classifyBuffer.value = ''
    closeToast()
  }
}

// 处理SSE事件
const handleSSEEvent = (eventType, data, classifyResults) => {
  console.log('收到事件:', eventType, data)
  if (eventType === 'data') {
    try {
      classifyBuffer.value += data

      let startIndex = 0
      while (startIndex < classifyBuffer.value.length) {
        const openBrace = classifyBuffer.value.indexOf('{', startIndex)
        if (openBrace === -1) {
          classifyBuffer.value = ''
          break
        }

        let braceCount = 0
        let closeBrace = -1
        for (let i = openBrace; i < classifyBuffer.value.length; i++) {
          if (classifyBuffer.value[i] === '{') {
            braceCount++
          } else if (classifyBuffer.value[i] === '}') {
            braceCount--
            if (braceCount === 0) {
              closeBrace = i
              break
            }
          }
        }

        if (closeBrace !== -1) {
          const jsonStr = classifyBuffer.value.substring(openBrace, closeBrace + 1)

          try {
            const result = JSON.parse(jsonStr)
            if (result.id && groupListRef.value) {
              classifyResults.set(result.id, {
                classify: result.Classify || '',
                type: result.Type !== undefined ? result.Type : null
              })

              // 更新组件内的分组显示状态
              const groups = groupListRef.value.getList()
              for (const group of groups) {
                if (group.transactionIds.includes(result.id)) {
                  group.sampleClassify = result.Classify || ''
                  if (result.Type !== undefined && result.Type !== null) {
                    group.sampleType = result.Type
                  }
                  hasChanges.value = true
                  break
                }
              }
              // 更新回组件（内部更新时抑制 data-changed 处理）
              suppressDataChanged.value = true
              groupListRef.value.setList(groups)
              // 确保在子组件内部事件触发后恢复标志并保持 hasChanges
              nextTick(() => {
                suppressDataChanged.value = false
                hasChanges.value = true
              })
            }
          } catch (e) {
            console.error('JSON解析失败:', e)
          }

          classifyBuffer.value = classifyBuffer.value.substring(closeBrace + 1)
          startIndex = 0
        } else {
          break
        }
      }
    } catch (error) {
      console.error('解析分类结果失败', error)
    }
  } else if (eventType === 'start') {
    showToast(data)
  } else if (eventType === 'end') {
    classifyBuffer.value = ''
    showToast('分类完成')
  } else if (eventType === 'error') {
    classifyBuffer.value = ''
    showToast(data)
  }
}

// 保存分类
const saveClassifications = async () => {
  if (!groupListRef.value) {
    return
  }

  // 收集所有已分类的账单
  const groups = groupListRef.value.getList()
  const itemsToUpdate = []

  for (const group of groups) {
    if (group.sampleClassify) {
      // 为该分组的所有账单添加分类
      for (const id of group.transactionIds) {
        itemsToUpdate.push({
          id: id,
          classify: group.sampleClassify,
          type: group.sampleType
        })
      }
    }
  }

  if (itemsToUpdate.length === 0) {
    showToast('没有需要保存的分类')
    return
  }

  showLoadingToast({
    message: '保存中...',
    forbidClick: true,
    duration: 0
  })

  try {
    const res = await batchUpdateClassify(itemsToUpdate)
    if (res.success) {
      showToast('保存成功')
      hasChanges.value = false
      // 重新加载数据
      await loadUnclassifiedCount()
      await groupListRef.value.refresh()
    } else {
      showToast(res.message || '保存失败')
    }
  } catch (error) {
    console.error('保存失败', error)
    showToast('保存失败')
  } finally {
    closeToast()
  }
}

onMounted(async () => {
  await loadUnclassifiedCount()
  // 触发组件加载数据
  if (groupListRef.value) {
    await groupListRef.value.loadData()
  }
})
</script>

<style scoped>
/* 统计信息 */
.stats-info {
  padding: 12px 12px 0 16px;
  font-size: 14px;
  color: var(--van-text-color-2);
}

.stats-value {
  font-weight: 500;
}

.action-btn {
  flex: 1;
  height: 44px;
}

/* 设置页面容器背景色 */
:deep(.van-nav-bar) {
  background: transparent !important;
}
</style>
