<template>
  <view class="page">
    <view class="header-fixed">
      <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
      <view class="header">
        <view class="nav-back" @tap="goBack">
          <Icon name="arrowLeft" :size="36" color="#2D1B1B" />
        </view>
        <text class="title">{{ editId ? '编辑记录' : '记一笔' }}</text>
        <view :style="{ width: capsuleRight + 88 + 'px' }"></view>
      </view>
    </view>

    <view class="type-toggle-wrap">
      <view class="type-toggle" :class="{ income: type === 'income' }">
        <view class="slider"></view>
        <view class="tab" :class="{ active: type === 'expense' }" @tap="switchType('expense')">支出</view>
        <view class="tab" :class="{ active: type === 'income' }" @tap="switchType('income')">收入</view>
      </view>
    </view>

    <AmountEditor
      ref="amountEditorRef"
      v-model="amountStr"
      :fixed="true"
      size="large"
      :auto-focus="true"
      @confirm="save"
    />

    <scroll-view class="category-scroll" scroll-y :scroll-into-view="scrollToCat" @tap="blurAmountEditor">
      <view class="category-grid">
        <view v-for="cat in currentCategories" :key="cat.id" :id="'cat-' + cat.id" class="cat-item" :class="{ suggested: suggestedCatId === cat.id && selectedCat !== cat.id }" @tap="selectedCat = cat.id">
          <view class="cat-icon-wrap">
            <CategoryIcon :label="cat.name[0]" :color="cat.color" :bg-color="cat.color + '15'" size="md" :selected="selectedCat === cat.id" />
            <view v-if="suggestedCatId === cat.id && selectedCat !== cat.id" class="suggest-badge">
              <text class="suggest-badge-text">推荐</text>
            </view>
          </view>
          <text class="cat-name" :class="{ active: selectedCat === cat.id }">{{ cat.name }}</text>
        </view>
      </view>
    </scroll-view>

    <view class="extra-fields">
      <picker mode="date" :value="selectedDate" :end="todayStr" @change="onDateChange">
        <view class="extra-row" @tap="blurAmountEditor">
          <Icon name="calendar" :size="28" color="#8B7E7E" />
          <text class="extra-text">{{ dateLabel }}</text>
        </view>
      </picker>
      <view class="extra-row">
        <Icon name="edit" :size="28" color="#8B7E7E" />
        <input class="extra-input" v-model="note" placeholder="添加备注..." placeholder-class="placeholder" maxlength="200" @focus="blurAmountEditor" />
      </view>
    </view>



    <SaveSuccess
      v-model:visible="showSuccess"
      :text="editId ? '修改成功' : '记账成功'"
      :showContinue="!editId"
      @continue="onContinue"
      @back="onBack"
    />
  </view>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, nextTick } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import { useCategoryStore } from '@/stores/category'
import { useTransactionStore } from '@/stores/transaction'
import { waitForReady } from '@/utils/app-ready'
import { suggestCategory } from '@/api/stats'
import AmountEditor from '@/components/AmountEditor/AmountEditor.vue'
import CategoryIcon from '@/components/CategoryIcon/CategoryIcon.vue'
import Icon from '@/components/Icon/Icon.vue'
import SaveSuccess from '@/components/SaveSuccess/SaveSuccess.vue'
import { statusBarHeight, capsuleRight } from '@/utils/system'

const catStore = useCategoryStore()
const txStore = useTransactionStore()

const type = ref<'expense' | 'income'>('expense')
const amountStr = ref('0')
const selectedCat = ref<number | null>(null)
const note = ref('')
const suggestedCatId = ref<number | null>(null)
const suggestConfidence = ref(0)
let suggestTimer: ReturnType<typeof setTimeout> | null = null
const now = new Date()
const localToday = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`
const selectedDate = ref(localToday)
const saving = ref(false)
const editId = ref<number | null>(null)
const showSuccess = ref(false)
const scrollToCat = ref('')
const todayStr = localToday
const amountEditorRef = ref<InstanceType<typeof AmountEditor> | null>(null)
// Remember last selected category per type
const lastCatByType: Record<string, number | null> = { expense: null, income: null }

const dateLabel = computed(() => {
  const d = new Date(selectedDate.value)
  return `${d.getMonth() + 1}月${d.getDate()}日`
})


const currentCategories = computed(() => catStore.getByType(type.value))

function switchType(newType: 'expense' | 'income') {
  // Remember current selection before switching
  lastCatByType[type.value] = selectedCat.value
  type.value = newType
  const cats = catStore.getByType(newType)
  // Restore last selection for this type, or fall back to first category
  const saved = lastCatByType[newType]
  if (saved && cats.find(c => c.id === saved)) {
    selectedCat.value = saved
  } else {
    selectedCat.value = cats.length > 0 ? cats[0].id : null
  }
}

watch(currentCategories, (cats) => {
  if (cats.length > 0 && !cats.find(c => c.id === selectedCat.value)) {
    selectedCat.value = cats[0].id
  }
})

// 智能分类推荐：监听金额和备注变化，防抖 600ms 后请求建议
watch([amountStr, note], () => {
  if (suggestTimer) clearTimeout(suggestTimer)
  suggestTimer = setTimeout(async () => {
    const amt = Math.round(parseFloat(amountStr.value || '0') * 100)
    if (amt <= 0 || editId.value) {
      suggestedCatId.value = null
      suggestConfidence.value = 0
      return
    }
    try {
      const result = await suggestCategory(amt, type.value, note.value)
      if (result.category && result.confidence >= 30) {
        suggestedCatId.value = result.category.id
        suggestConfidence.value = result.confidence
        // 置信度 >= 60 时自动选中
        if (result.confidence >= 60 && !editId.value) {
          selectedCat.value = result.category.id
        }
      } else {
        suggestedCatId.value = null
        suggestConfidence.value = 0
      }
    } catch {
      suggestedCatId.value = null
    }
  }, 600)
})

onMounted(async () => {
  await waitForReady()

  // 加载分类列表，失败时重试一次
  try {
    await catStore.fetchCategories()
  } catch {
    try {
      await catStore.fetchCategories()
    } catch {
      uni.showToast({ title: '分类加载失败', icon: 'none' })
    }
  }

  const pages = getCurrentPages()
  const page = pages[pages.length - 1] as { options?: Record<string, string> }
  if (page?.options?.type && ['expense', 'income'].includes(page.options.type)) {
    type.value = page.options.type
  }
  if (page?.options?.editId) {
    editId.value = Number(page.options.editId)
    // Try to find in store first, otherwise fetch from server
    let existing = txStore.transactions.find(t => t.id === editId.value)
    if (!existing) {
      existing = await txStore.fetchTransactionById(editId.value!)
    }
    if (existing) {
      type.value = existing.type
      amountStr.value = (existing.amount / 100).toFixed(2)
      selectedCat.value = existing.category_id
      lastCatByType[existing.type] = existing.category_id
      note.value = existing.note || ''
      selectedDate.value = existing.date.slice(0, 10)
      // 等待分类列表渲染完成后滚动到选中项
      nextTick(() => {
        setTimeout(() => { scrollToCat.value = 'cat-' + existing.category_id }, 200)
        amountEditorRef.value?.focus()
      })
    } else {
      uni.showToast({ title: '记录不存在', icon: 'none' })
      setTimeout(() => uni.navigateBack(), 1500)
    }
  }
  if (currentCategories.value.length > 0 && !selectedCat.value) {
    selectedCat.value = currentCategories.value[0].id
  }
  initialLoaded.value = true
})

// 返回页面时刷新分类（可能新增了分类）
const initialLoaded = ref(false)
onShow(() => {
  if (initialLoaded.value) catStore.fetchCategories()
})

function onDateChange(e: any) {
  selectedDate.value = e.detail.value
}

function blurAmountEditor() {
  amountEditorRef.value?.blur()
}

async function save() {
  if (saving.value) return
  const amount = Math.round(parseFloat(amountStr.value || '0') * 100)
  if (isNaN(amount) || amount <= 0) {
    uni.showToast({ title: '请输入金额', icon: 'none' })
    return
  }
  if (!selectedCat.value) {
    uni.showToast({ title: '请选择分类', icon: 'none' })
    return
  }

  saving.value = true
  try {
    const data = {
      amount,
      type: type.value,
      category_id: selectedCat.value,
      note: note.value,
      date: selectedDate.value
    }
    if (editId.value) {
      await txStore.updateTransaction(editId.value, data)
    } else {
      await txStore.addTransaction(data)
    }
    showSuccess.value = true
    // 编辑模式自动返回，新增模式显示继续按钮
    if (editId.value) {
      setTimeout(() => uni.navigateBack(), 2000)
    }
  } catch (e) {
    uni.showToast({ title: '保存失败', icon: 'none' })
  } finally {
    saving.value = false
  }
}

/** 继续记一笔 */
function onContinue() {
  // 重置表单，保留分类和日期
  amountStr.value = ''
  note.value = ''
  showSuccess.value = false
  nextTick(() => amountEditorRef.value?.focus())
}

/** 返回上一页 */
function onBack() {
  uni.navigateBack()
}

function goBack() {
  // 保存成功后直接返回，不弹确认框
  if (showSuccess.value) return
  const hasInput = amountStr.value !== '0' || note.value
  if (hasInput) {
    uni.showModal({
      title: '提示',
      content: '放弃当前记录？',
      success: (res) => {
        if (res.confirm) uni.navigateBack()
      }
    })
  } else {
    uni.navigateBack()
  }
}
</script>

<style lang="scss" scoped>
@import '@/styles/mixins.scss';

.page {
  min-height: 100vh;
  background: $bg;
  display: flex;
  flex-direction: column;
  // AmountEditor fixed Numpad 占位: 4行×96rpx + 3间隙×16rpx + padding×2×16rpx = 464rpx
  $numpad-h: 464rpx;
  padding-bottom: calc(#{$numpad-h} + constant(safe-area-inset-bottom));
  padding-bottom: calc(#{$numpad-h} + env(safe-area-inset-bottom));
}

.header-fixed {
  @include sticky-header;
}

.status-bar {
  @include status-bar;
}

.header {
  @include nav-bar;
  justify-content: space-between;
}

.nav-back {
  @include nav-back;
  border-radius: 50%;

  &:active { background: $border; }
}

.title { font-size: $font-xl; font-weight: 500; color: $text; }

.type-toggle-wrap {
  display: flex; justify-content: center;
  margin: $space-sm 0;
  @include fade-in-up;
}

.type-toggle {
  display: inline-flex;
  background: $surface-warm;
  border-radius: $radius-lg;
  padding: $space-xs;
  position: relative;
}

.tab {
  width: 160rpx;
  height: 72rpx;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: $font-lg;
  color: $text-sec;
  border-radius: $radius-lg;
  position: relative;
  z-index: 1;
  transition: color $transition-normal;

  &.active { color: $primary; font-weight: 600; }
}

.slider {
  position: absolute;
  top: $space-xs;
  left: $space-xs;
  width: 160rpx;
  height: 72rpx;
  background: $surface;
  border-radius: $radius-lg;
  box-shadow: $shadow-sm;
  transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1);
}

.income .slider { transform: translateX(160rpx); }


.category-scroll {
  max-height: 320rpx;
}

.category-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: $space-sm;
  padding: $space-xs 0;
}

.cat-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6rpx;
  padding: 12rpx 0;
  position: relative;
  -webkit-tap-highlight-color: transparent;

  &:active { transform: scale(0.92); }

  &.suggested {
    .cat-icon-wrap {
      border: 3rpx dashed $primary;
      border-radius: $radius-lg;
      padding: 6rpx;
      margin: -6rpx;
      animation: suggest-pulse 2s ease-in-out infinite;
    }
  }
}

@keyframes suggest-pulse {
  0%, 100% { border-color: $primary; }
  50% { border-color: lighten($primary, 30%); }
}

.cat-icon-wrap {
  position: relative;
  transition: all $transition-normal;
}

.suggest-badge {
  position: absolute;
  top: -8rpx;
  right: -12rpx;
  padding: 2rpx 10rpx;
  background: $primary;
  border-radius: $radius-xs;
}

.suggest-badge-text {
  font-size: 18rpx;
  color: $surface;
  font-weight: 600;
}

.cat-name { font-size: $font-sm; color: $text-sec; }

.cat-name.active {
  color: $primary;
  font-weight: 600;
}

.extra-fields {
  padding: $space-sm $space-xl;
  display: flex;
  flex-direction: column;
  gap: 12rpx;
}

.extra-row {
  height: 88rpx;
  background: $surface;
  border-radius: $radius-lg;
  border: 2rpx solid $border;
  padding: 0 $space-md;
  display: flex;
  align-items: center;
  gap: 12rpx;
}

.extra-text { font-size: $font-lg; color: $text; flex: 1; }
.extra-input { font-size: $font-lg; color: $text; flex: 1; }

.placeholder { color: $text-muted; }



</style>
