<template>
  <view class="page">
    <view class="header-fixed">
      <view class="status-bar" :style="{ height: statusBarHeight + 'px' }"></view>
      <view class="nav-bar" :style="{ paddingRight: capsuleRight + 'px' }">
        <view class="nav-back" @tap="goBack">
          <Icon name="arrowLeft" :size="40" color="#2D1B1B" />
        </view>
        <text class="nav-title">周期账单</text>
        <view class="nav-action" @tap="openAddModal">
          <Icon name="plus" :size="40" color="#FF8C69" />
        </view>
      </view>
    </view>

    <!-- 同步提示 -->
    <view class="sync-bar" v-if="syncCount > 0" @tap="syncCount = 0">
      <Icon name="check" :size="28" color="#43A047" />
      <text class="sync-text">已自动生成 {{ syncCount }} 笔记录</text>
    </view>

    <!-- 加载/空/列表 -->
    <view v-if="loading" class="loading-box">
      <text class="loading-text">加载中...</text>
    </view>

    <view v-else-if="list.length === 0" class="empty-box">
      <Icon name="edit" :size="48" color="#BFB3B3" />
      <text class="empty-text">暂无周期账单</text>
      <text class="empty-hint">设置房租、订阅、工资等定期收支</text>
      <view class="empty-btn" @tap="openAddModal">
        <text class="empty-btn-text">添加周期账单</text>
      </view>
    </view>

    <scroll-view v-else class="list" scroll-y>
      <view v-for="item in list" :key="item.id" class="template-card" :class="{ inactive: !item.is_active }">
        <view class="card-main" @tap="openEditModal(item)">
          <CategoryIcon :label="(item.category_name || '?')[0]" :color="item.category_color || '#FF8C69'" :bg-color="(item.category_color || '#FF8C69') + '15'" size="md" />
          <view class="card-info">
            <view class="card-title-row">
              <text class="card-name">{{ item.category_name || '未分类' }}</text>
              <text class="card-frequency">{{ freqMap[item.frequency] }}</text>
            </view>
            <text class="card-note" v-if="item.note">{{ item.note }}</text>
            <text class="card-date">下次：{{ item.next_date }} {{ item.end_date ? '· 至 ' + item.end_date : '' }}</text>
          </view>
          <text class="card-amount" :class="item.type">{{ item.type === 'expense' ? '-' : '+' }}{{ formatAmount(item.amount) }}</text>
        </view>
        <view class="card-actions">
          <view class="card-switch" @tap="toggleActive(item)">
            <view class="switch-track" :class="{ on: item.is_active }">
              <view class="switch-thumb"></view>
            </view>
            <text class="switch-label">{{ item.is_active ? '开启' : '暂停' }}</text>
          </view>
          <view class="card-btn" @tap="openEditModal(item)">
            <Icon name="edit" :size="24" color="#8B7E7E" />
          </view>
          <view class="card-btn" @tap="handleDelete(item)">
            <Icon name="trash" :size="24" color="#FF6B6B" />
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 添加/编辑弹窗 -->
    <view class="modal-mask" v-if="showModal" @tap="showModal = false">
      <view class="form-modal" @tap.stop>
        <view class="modal-header">
          <text class="modal-title">{{ editingId ? '编辑周期账单' : '添加周期账单' }}</text>
          <view class="modal-close" @tap="showModal = false">
            <text class="modal-close-text">×</text>
          </view>
        </view>
        <scroll-view class="modal-body" scroll-y>
          <!-- 类型切换 -->
          <view class="type-toggle-wrap">
            <view class="type-toggle" :class="{ income: form.type === 'income' }">
              <view class="slider"></view>
              <view class="tab" :class="{ active: form.type === 'expense' }" @tap="form.type = 'expense'">支出</view>
              <view class="tab" :class="{ active: form.type === 'income' }" @tap="form.type = 'income'">收入</view>
            </view>
          </view>

          <!-- 金额 -->
          <view class="amount-row">
            <text class="currency">¥</text>
            <text class="digits" :class="{ placeholder: !amountStr }">{{ amountStr || '0' }}</text>
          </view>

          <!-- 分类 -->
          <scroll-view class="category-scroll" scroll-x>
            <view class="category-row">
              <view v-for="cat in currentCategories" :key="cat.id" class="cat-item" @tap="form.category_id = cat.id">
                <CategoryIcon :label="cat.name[0]" :color="cat.color" :bg-color="cat.color + '15'" size="sm" :selected="form.category_id === cat.id" />
                <text class="cat-name" :class="{ active: form.category_id === cat.id }">{{ cat.name }}</text>
              </view>
            </view>
          </scroll-view>

          <!-- 备注 -->
          <view class="form-item">
            <Icon name="edit" :size="28" color="#8B7E7E" />
            <input class="form-input" v-model="form.note" placeholder="备注（可选）" maxlength="50" />
          </view>

          <!-- 周期 -->
          <view class="form-item">
            <Icon name="calendar" :size="28" color="#8B7E7E" />
            <view class="freq-options">
              <view v-for="f in frequencies" :key="f.value" class="freq-tab" :class="{ active: form.frequency === f.value }" @tap="form.frequency = f.value">
                <text class="freq-text">{{ f.label }}</text>
              </view>
            </view>
          </view>

          <!-- 开始日期 -->
          <view class="form-item">
            <text class="form-label">开始日期</text>
            <picker mode="date" :value="form.next_date" @change="e => form.next_date = e.detail.value">
              <view class="form-picker">
                <text class="form-picker-text">{{ form.next_date }}</text>
              </view>
            </picker>
          </view>

          <!-- 结束日期 -->
          <view class="form-item">
            <text class="form-label">结束日期</text>
            <picker mode="date" :value="form.end_date || ''" :start="form.next_date" @change="e => form.end_date = e.detail.value">
              <view class="form-picker">
                <text class="form-picker-text" :class="{ placeholder: !form.end_date }">{{ form.end_date || '永久（不自动结束）' }}</text>
              </view>
            </picker>
          </view>

        </scroll-view>

        <!-- 数字键盘：在滚动区外，始终可见，避免 scroll-view 吞事件 -->
        <Numpad v-model="amountStr" :fixed="false" @confirm="handleSubmit" />

        <view class="modal-footer" @tap="handleSubmit">
          <text class="submit-text">{{ editingId ? '保存修改' : '添加' }}</text>
        </view>
      </view>
    </view>

  </view>
</template>

<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'
import { waitForReady } from '@/utils/app-ready'
import { statusBarHeight, capsuleRight } from '@/utils/system'
import { formatAmount } from '@/utils/format'
import { useCategoryStore } from '@/stores/category'
import { getRecurringTemplates, createRecurringTemplate, updateRecurringTemplate, deleteRecurringTemplate, syncRecurring } from '@/api/recurring'
import Icon from '@/components/Icon/Icon.vue'
import CategoryIcon from '@/components/CategoryIcon/CategoryIcon.vue'
import Numpad from '@/components/Numpad/Numpad.vue'
import type { RecurringTemplate } from '@/api/recurring'
import type { Category } from '@/stores/category'

const catStore = useCategoryStore()

const list = ref<RecurringTemplate[]>([])
const loading = ref(true)
const showModal = ref(false)
const editingId = ref<number | null>(null)
const amountStr = ref('')
const saving = ref(false)
const syncCount = ref(0)

const freqMap: Record<string, string> = {
  weekly: '每周', monthly: '每月', yearly: '每年'
}
const frequencies = [
  { value: 'monthly' as const, label: '每月' },
  { value: 'weekly' as const, label: '每周' },
  { value: 'yearly' as const, label: '每年' },
]

const defaultForm = {
  type: 'expense' as 'expense' | 'income',
  category_id: 0,
  note: '',
  frequency: 'monthly' as 'weekly' | 'monthly' | 'yearly',
  next_date: getTodayStr(),
  end_date: '' as string,
}
const form = ref({ ...defaultForm })

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

function getTodayStr(): string {
  const d = new Date()
  return `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
}

onMounted(async () => {
  await waitForReady()
  await Promise.all([loadList(), syncAndLoad()])
})

async function loadList() {
  loading.value = true
  try {
    list.value = await getRecurringTemplates()
  } catch { } finally {
    loading.value = false
  }
}

async function syncAndLoad() {
  try {
    // 同步到期账单（静默，失败不影响主流程）
    const result = await syncRecurring()
    if (result.generated > 0) {
      syncCount.value = result.generated
      setTimeout(() => { syncCount.value = 0 }, 5000)
    }
  } catch { }
}

function openAddModal() {
  editingId.value = null
  form.value = { ...defaultForm, next_date: getTodayStr() }
  const cats = catStore.getByType('expense')
  if (cats.length > 0) form.value.category_id = cats[0].id
  amountStr.value = ''
  showModal.value = true
}

function openEditModal(item: RecurringTemplate) {
  editingId.value = item.id
  form.value = {
    type: item.type,
    category_id: item.category_id,
    note: item.note,
    frequency: item.frequency,
    next_date: item.next_date,
    end_date: item.end_date || '',
  }
  amountStr.value = (item.amount / 100).toString()
  showModal.value = true
}

async function toggleActive(item: RecurringTemplate) {
  const newState = item.is_active ? 0 : 1
  try {
    await updateRecurringTemplate(item.id, { is_active: newState })
    item.is_active = newState
  } catch {
    uni.showToast({ title: '操作失败', icon: 'none' })
  }
}

async function handleSubmit() {
  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 (!form.value.category_id) {
    uni.showToast({ title: '请选择分类', icon: 'none' })
    return
  }

  saving.value = true
  try {
    const data = {
      amount,
      type: form.value.type,
      category_id: form.value.category_id,
      note: form.value.note,
      frequency: form.value.frequency,
      next_date: form.value.next_date,
      end_date: form.value.end_date || undefined,
    }
    if (editingId.value) {
      await updateRecurringTemplate(editingId.value, data)
    } else {
      await createRecurringTemplate(data)
    }
    showModal.value = false
    await loadList()
    uni.showToast({ title: editingId.value ? '已更新' : '已添加', icon: 'success' })
  } catch {
    uni.showToast({ title: '保存失败', icon: 'none' })
  } finally {
    saving.value = false
  }
}

async function handleDelete(item: RecurringTemplate) {
  uni.showModal({
    title: '删除周期账单',
    content: `确定删除「${item.category_name || ''} ${formatAmount(item.amount)}」？已生成的记录不受影响。`,
    success: async (res) => {
      if (res.confirm) {
        try {
          await deleteRecurringTemplate(item.id)
          list.value = list.value.filter(t => t.id !== item.id)
          uni.showToast({ title: '已删除', icon: 'success' })
        } catch {
          uni.showToast({ title: '删除失败', icon: 'none' })
        }
      }
    }
  })
}

function goBack() { uni.navigateBack() }
</script>

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

.page { min-height: 100vh; background: $bg; padding-bottom: 120rpx; }
.header-fixed { @include sticky-header; }
.status-bar { @include status-bar; }

.nav-bar {
  display: flex; align-items: center;
  padding: $space-sm $space-xl $space-md;
}
.nav-back { @include nav-back; }
.nav-title {
  flex: 1; text-align: center;
  font-size: $font-2xl; font-weight: 600; color: $text;
}
.nav-action {
  width: 88rpx; height: 88rpx; @include flex-center;
  &:active { opacity: 0.6; }
}

.sync-bar {
  display: flex; align-items: center; gap: $space-xs;
  margin: $space-sm $space-xl; padding: $space-sm $space-md;
  background: #E8F5E9; border-radius: $radius-lg;
  &:active { opacity: 0.8; }
}
.sync-text { font-size: $font-md; color: #43A047; font-weight: 500; }

.loading-box, .empty-box {
  display: flex; flex-direction: column; align-items: center;
  padding: 120rpx 0; gap: $space-sm;
}
.loading-text, .empty-text { font-size: $font-lg; color: $text-muted; }
.empty-hint { font-size: $font-md; color: $text-muted; margin-top: -$space-xs; }
.empty-btn {
  margin-top: $space-lg; padding: $space-sm $space-xl;
  background: $primary; border-radius: $radius-lg;
  &:active { opacity: 0.8; }
}
.empty-btn-text { font-size: $font-base; color: $surface; font-weight: 600; }

.list { padding: 0 $space-xl; max-height: calc(100vh - 200rpx); }

.template-card {
  background: $surface; border-radius: $radius-xl;
  border: 2rpx solid $border; box-shadow: $shadow-md;
  padding: $space-lg; margin-bottom: $space-sm;
  &.inactive { opacity: 0.6; }
}

.card-main {
  display: flex; align-items: center; gap: $space-md;
  &:active { opacity: 0.7; }
}

.card-info { flex: 1; min-width: 0; }
.card-title-row { display: flex; align-items: center; gap: $space-sm; }
.card-name { font-size: $font-lg; font-weight: 600; color: $text; }
.card-frequency {
  font-size: $font-xs; color: $primary; background: $primary-light;
  padding: 2rpx 10rpx; border-radius: $radius-xs;
}
.card-note {
  font-size: $font-sm; color: $text-sec;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  margin-top: 2rpx;
}
.card-date { font-size: $font-sm; color: $text-muted; margin-top: 2rpx; display: block; }
.card-amount {
  font-family: 'Fredoka', sans-serif; font-size: $font-xl; font-weight: 600;
  &.expense { color: $text; } &.income { color: $success; }
}

.card-actions {
  display: flex; align-items: center; gap: $space-md;
  margin-top: $space-sm; padding-top: $space-sm;
  border-top: 2rpx solid $border;
}
.card-switch {
  display: flex; align-items: center; gap: $space-sm;
  flex: 1;
}
.switch-track {
  width: 44rpx; height: 24rpx; border-radius: 12rpx;
  background: #D0C4C4; position: relative; transition: background $transition-normal;
  &.on { background: $primary; }
}
.switch-thumb {
  position: absolute; top: 2rpx; left: 2rpx;
  width: 20rpx; height: 20rpx; border-radius: 50%;
  background: $surface; transition: transform $transition-normal;
  .on & { transform: translateX(20rpx); }
}
.switch-label { font-size: $font-sm; color: $text-muted; }
.card-btn {
  width: 64rpx; height: 64rpx; @include flex-center; border-radius: 50%;
  &:active { background: $bg; }
}

/* 表单弹窗 */
.modal-mask { @include modal-mask; }
.form-modal {
  width: 100%; max-height: 90vh; background: $surface;
  border-radius: $radius-2xl $radius-2xl 0 0;
  display: flex; flex-direction: column; margin-top: auto;
  padding-bottom: env(safe-area-inset-bottom);
}
.modal-header {
  display: flex; align-items: center; justify-content: space-between;
  padding: $space-lg $space-xl $space-md; border-bottom: 2rpx solid $border;
}
.modal-title { font-size: $font-xl; font-weight: 600; color: $text; }
.modal-close {
  width: 56rpx; height: 56rpx; @include flex-center; border-radius: 50%; background: $border;
  &:active { background: darken($border, 5%); }
}
.modal-close-text { font-size: $font-2xl; color: $text-sec; line-height: 1; }
.modal-body { flex: 1; padding: $space-md $space-xl; max-height: 45vh; }
.modal-footer {
  padding: $space-md $space-xl; border-top: 2rpx solid $border;
}

.submit-text {
  display: block; text-align: center; font-size: 30rpx; font-weight: 600; color: $surface;
  padding: $space-lg; background: linear-gradient(135deg, $primary, #E67355);
  border-radius: $radius-lg;
  &:active { opacity: 0.8; }
}

/* 类型切换 */
.type-toggle-wrap { display: flex; justify-content: center; margin-bottom: $space-md; }
.type-toggle {
  display: inline-flex; background: $surface-warm; border-radius: $radius-lg;
  padding: $space-xs; position: relative;
}
.tab {
  width: 140rpx; height: 64rpx; display: flex; align-items: center; justify-content: center;
  font-size: $font-md; color: $text-sec; border-radius: $radius-md; position: relative; z-index: 1;
  &.active { color: $primary; font-weight: 600; }
}
.slider {
  position: absolute; top: $space-xs; left: $space-xs; width: 140rpx; height: 64rpx;
  background: $surface; border-radius: $radius-md; box-shadow: $shadow-sm;
  transition: transform $transition-normal;
}
.income .slider { transform: translateX(140rpx); }

/* 金额 */
.amount-row {
  text-align: center; padding: $space-sm 0 $space-md;
}
.currency {
  font-family: 'Fredoka', sans-serif; font-size: $space-2xl; font-weight: 500;
  color: $text-muted; margin-right: $space-xs;
}
.digits {
  font-family: 'Fredoka', sans-serif; font-size: 72rpx; font-weight: 600; color: $text;
  &.placeholder { color: #D0C4C4; }
}

/* 分类 */
.category-scroll { margin-bottom: $space-md; }
.category-row { display: flex; gap: $space-sm; padding: $space-xs 0; }
.cat-item {
  display: flex; flex-direction: column; align-items: center; gap: 6rpx;
  padding: 8rpx 12rpx; min-width: 100rpx;
  &:active { opacity: 0.7; }
}
.cat-name { font-size: $font-sm; color: $text-sec; &.active { color: $primary; font-weight: 600; } }

/* 表单项 */
.form-item {
  display: flex; align-items: center; gap: $space-sm;
  height: 80rpx; margin-bottom: $space-sm;
  padding: 0 $space-md; background: $bg; border-radius: $radius-lg;
  border: 2rpx solid $border;
}
.form-label { font-size: $font-md; color: $text-sec; flex-shrink: 0; margin-right: $space-sm; }
.form-input { flex: 1; font-size: $font-md; color: $text; }
.form-picker { flex: 1; }
.form-picker-text { font-size: $font-md; color: $text; &.placeholder { color: $text-muted; } }
.freq-options { display: flex; gap: $space-xs; }
.freq-tab {
  padding: $space-xs $space-lg; border-radius: $radius-md;
  font-size: $font-md; color: $text-sec; background: $surface;
  border: 2rpx solid $border;
  &.active { background: $primary; color: $surface; border-color: $primary; }
  &:active { opacity: 0.8; }
}

</style>
