﻿<template>
  <div class="bill-form">
    <van-form @submit="handleSubmit">
      <van-cell-group inset>
        <!-- 日期时间 -->
        <van-field label="时间">
          <template #input>
            <div style="display: flex; gap: 16px">
              <div @click="showDatePicker = true">{{ form.date }}</div>
              <div @click="showTimePicker = true">{{ form.time }}</div>
            </div>
          </template>
        </van-field>

        <!-- 金额 -->
        <van-field
          v-model="form.amount"
          name="amount"
          label="金额"
          type="number"
          placeholder="0.00"
          :rules="[{ required: true, message: '请输入金额' }]"
        />

        <!-- 备注 -->
        <van-field
          v-model="form.note"
          name="note"
          label="摘要"
          placeholder="摘要信息"
          rows="2"
          autosize
          type="textarea"
        />

        <!-- 交易类型 -->
        <van-field name="type" label="类型">
          <template #input>
            <van-radio-group v-model="form.type" direction="horizontal">
              <van-radio :name="0">支出</van-radio>
              <van-radio :name="1">收入</van-radio>
              <van-radio :name="2">不计</van-radio>
            </van-radio-group>
          </template>
        </van-field>

        <!-- 分类 -->
        <van-field name="category" label="分类">
          <template #input>
            <span v-if="!categoryName" style="color: #c8c9cc;">请选择分类</span>
            <span v-else>{{ categoryName }}</span>
          </template>
        </van-field>
        
        <!-- 分类按钮网格 -->
        <div class="classify-buttons">
          <van-button
            type="success"
            size="small"
            class="classify-btn"
            @click="showAddClassify = true"
          >
            + 新增
          </van-button>
          <van-button
            v-for="item in categoryList"
            :key="item.id"
            :type="categoryName === item.name ? 'primary' : 'default'"
            size="small"
            class="classify-btn"
            @click="selectClassify(item)"
          >
            {{ item.name }}
          </van-button>
        </div>
      </van-cell-group>

      <div class="actions">
        <van-button round block type="primary" native-type="submit" :loading="loading">
          {{ submitText }}
        </van-button>
        <slot name="actions"></slot>
      </div>
    </van-form>

    <!-- 新增分类对话框 -->
    <van-dialog 
      v-model:show="showAddClassify" 
      title="新增交易分类" 
      show-cancel-button
      @confirm="addNewClassify"
    >
      <van-field v-model="newClassify" placeholder="请输入新的交易分类" />
    </van-dialog>

    <!-- 日期选择弹窗 -->
    <van-popup v-model:show="showDatePicker" position="bottom" round>
      <van-date-picker
        v-model="currentDate"
        title="选择日期"
        @confirm="onConfirmDate"
        @cancel="showDatePicker = false"
      />
    </van-popup>

    <!-- 时间选择弹窗 -->
    <van-popup v-model:show="showTimePicker" position="bottom" round>
      <van-time-picker
        v-model="currentTime"
        title="选择时间"
        @confirm="onConfirmTime"
        @cancel="showTimePicker = false"
      />
    </van-popup>
  </div>
</template>

<script setup>
import { ref, onMounted, watch } from 'vue'
import { showToast } from 'vant'
import dayjs from 'dayjs'
import { getCategoryList, createCategory } from '@/api/transactionCategory'

const props = defineProps({
  initialData: {
    type: Object,
    default: () => ({})
  },
  loading: {
    type: Boolean,
    default: false
  },
  submitText: {
    type: String,
    default: '保存'
  }
})

const emit = defineEmits(['submit'])

// 表单数据
const form = ref({
  type: 0, // 0: 支出, 1: 收入, 2: 不计
  amount: '',
  categoryId: null,
  date: dayjs().format('YYYY-MM-DD'),
  time: dayjs().format('HH:mm'),
  note: ''
})

const categoryName = ref('')

// 弹窗控制
const showDatePicker = ref(false)
const showTimePicker = ref(false)
const showAddClassify = ref(false)
const newClassify = ref('')

// 选择器数据
const categoryList = ref([])

// 日期时间临时变量 (Vant DatePicker 需要数组或特定格式)
const currentDate = ref(dayjs().format('YYYY-MM-DD').split('-'))
const currentTime = ref(dayjs().format('HH:mm').split(':'))

// 初始化数据
const initForm = async () => {
  if (props.initialData) {
    const { occurredAt, amount, reason, type, classify } = props.initialData
    
    if (occurredAt) {
      const dt = dayjs(occurredAt)
      form.value.date = dt.format('YYYY-MM-DD')
      form.value.time = dt.format('HH:mm')
      currentDate.value = form.value.date.split('-')
      currentTime.value = form.value.time.split(':')
    }
    
    if (amount !== undefined) form.value.amount = amount
    if (reason !== undefined) form.value.note = reason
    if (type !== undefined) form.value.type = type
    
    // 加载分类列表
    await loadClassifyList(form.value.type)
    
    // 如果有传入分类名称，尝试匹配
    if (classify) {
      const found = categoryList.value.find(c => c.name === classify)
      if (found) {
        selectClassify(found)
      } else {
        // 如果没找到对应分类，但有分类名称，可能需要特殊处理或者就显示名称但不关联ID？
        // 这里暂时只显示名称，ID为空，或者需要自动创建？
        // 按照原有逻辑，后端需要分类名称，所以这里只要设置 categoryName 即可
        // 但是 ManualBillAdd 原逻辑是需要 categoryId 的。
        // 不过 createTransaction 接口传的是 classify (name)。
        // 让我们看 ManualBillAdd 的 handleSave:
        // classify: categoryName.value
        // 所以只要 categoryName 有值就行。
        categoryName.value = classify
      }
    }
  } else {
    await loadClassifyList(form.value.type)
  }
}

onMounted(() => {
  initForm()
})

// 监听 initialData 变化 (例如重新解析后)
watch(() => props.initialData, () => {
  initForm()
}, { deep: true })

// 监听交易类型变化，重新加载分类
watch(() => form.value.type, (newVal) => {
  // 如果是初始化过程中导致的类型变化，可能不需要清空分类（如果已经匹配好了）
  // 但如果是用户手动切换，应该清空
  // 这里简单处理：如果是用户切换，通常需要重新选择。
  // 为了避免初始化时的冲突，可以在 initForm 里处理好。
  // 这里主要响应用户操作。
  
  // 只有当当前分类不属于新类型时才清空？或者总是清空？
  // 原逻辑是总是清空。
  // 但是如果是 initForm 引起的，我们不希望清空。
  // 暂时保持原逻辑，但在 initForm 里调用 loadClassifyList 后再设置 categoryName
  
  // 简单的做法：在 watch 内部判断是否正在初始化？比较麻烦。
  // 或者：只在用户点击 radio 时触发？
  // watch 是最稳妥的，但要注意 initForm 里的顺序。
  // 在 initForm 里，我们先设置 type，这会触发 watch。
  // 所以 initForm 里的 loadClassifyList 可能会被 watch 里的覆盖。
  // 让我们调整一下策略：
  // 不在 watch 里加载，而是由 radio change 事件触发？
  // 或者在 watch 里判断，如果 categoryName 已经有值且符合当前类型（这个很难判断），就不清空。
  
  // 实际上，initForm 里设置 type 后，watch 会执行。
  // watch 会清空 categoryName。
  // 所以 initForm 里设置 type 后，再设置 categoryName 是没用的，除非 watch 是异步的或者我们在 nextTick 设置。
  
  // 让我们修改 watch 逻辑，或者在 initForm 里处理。
  // 更好的方式：
  // 移除 watch，改为在 radio group 上 @change="handleTypeChange"
})

const handleTypeChange = (newType) => {
  categoryName.value = ''
  form.value.categoryId = null
  loadClassifyList(newType)
}

const loadClassifyList = async (type = null) => {
  try {
    const response = await getCategoryList(type)
    if (response.success) {
      categoryList.value = response.data || []
    }
  } catch (error) {
    console.error('加载分类列表出错:', error)
  }
}

const selectClassify = (item) => {
  categoryName.value = item.name
  form.value.categoryId = item.id
}

const addNewClassify = async () => {
  if (!newClassify.value.trim()) {
    showToast('请输入分类名称')
    return
  }
  
  try {
    const name = newClassify.value.trim()
    
    // 调用API创建分类
    const response = await createCategory({
      name: name,
      type: form.value.type
    })
    
    if (response.success) {
      showToast('分类创建成功')
      const newId = response.data
      // 重新加载分类列表
      await loadClassifyList(form.value.type)
      
      // 选中新创建的分类
      categoryName.value = name
      form.value.categoryId = newId
    } else {
      showToast(response.message || '创建分类失败')
    }
  } catch (error) {
    console.error('创建分类出错:', error)
    showToast('创建分类失败')
  } finally {
    newClassify.value = ''
    showAddClassify.value = false
  }
}

const onConfirmDate = ({ selectedValues }) => {
  form.value.date = selectedValues.join('-')
  showDatePicker.value = false
}

const onConfirmTime = ({ selectedValues }) => {
  form.value.time = selectedValues.join(':')
  showTimePicker.value = false
}

const handleSubmit = () => {
  if (!form.value.amount) {
    showToast('请输入金额')
    return
  }
  if (!categoryName.value) {
    showToast('请选择分类')
    return
  }

  const fullDateTime = `${form.value.date}T${form.value.time}:00`
  
  const payload = {
    occurredAt: fullDateTime,
    classify: categoryName.value,
    amount: parseFloat(form.value.amount),
    reason: form.value.note || '',
    type: form.value.type
  }
  
  emit('submit', payload)
}

// 暴露重置方法给父组件
const reset = () => {
  form.value.amount = ''
  form.value.note = ''
  // 保留日期和类型
}

defineExpose({ reset })
</script>

<style scoped>
.bill-form {
  padding-top: 10px;
}
.actions {
  margin: 20px 16px;
}
.classify-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  padding: 12px 16px;
}
.classify-btn {
  flex: 0 0 auto;
  min-width: 70px;
  border-radius: 16px;
}
</style>
