<template>
  <view class="tx-item-wrap" :class="{ 'show-hint': swipeHint && !disableSwipe }">
    <view
      class="tx-item"
      :style="{ transform: `translateX(${offsetX}rpx)` }"
      @tap="$emit('item-tap', item)"
      @touchstart="!disableSwipe && onTouchStart($event)"
      @touchmove="!disableSwipe && onTouchMove($event)"
      @touchend="!disableSwipe && onTouchEnd()"
    >
      <!-- 始终显示分类图标 -->
      <CategoryIcon
        :label="item.category_name?.[0] || '?'"
        :color="item.category_color || '#BFB3B3'"
        :bg-color="(item.category_color || '#BFB3B3') + '20'"
        size="sm"
      />
      <view class="info">
        <text class="name">{{ item.note || item.category_name || '未分类' }}</text>
        <view class="meta">
          <view v-if="isOtherCreator" class="creator-tag">
            <image v-if="creatorAvatarUrl" :src="creatorAvatarUrl" class="creator-mini-avatar" mode="aspectFill" />
            <text v-else class="creator-mini-initial">{{ item.creator_nickname?.[0] }}</text>
            <text class="creator-name">{{ item.creator_nickname }}</text>
          </view>
          <text>{{ (isOtherCreator ? ' · ' : '') + (item.category_name || '未分类') }}{{ hideDate ? '' : ' · ' + formatDate(item.date) }}</text>
        </view>
      </view>
      <text class="amount" :class="item.type">{{ item.type === 'expense' ? '-' : '+' }}{{ formatAmount(item.amount) }}</text>
    </view>
    <view class="delete-btn" :class="{ visible: showDelete }" @tap="$emit('delete', item)">
      <Icon name="trash" :size="32" color="#FFFFFF" />
    </view>
  </view>
</template>

<script setup lang="ts">
import { ref, computed } from 'vue'
import { formatAmount, formatDate } from '@/utils/format'
import { API_BASE } from '@/config'
import Icon from '@/components/Icon/Icon.vue'
import CategoryIcon from '@/components/CategoryIcon/CategoryIcon.vue'

const props = withDefaults(defineProps<{
  item: {
    id: number
    user_id: number
    amount: number
    type: 'expense' | 'income'
    note?: string
    date: string
    category_name?: string
    category_icon?: string
    category_color?: string
    creator_nickname?: string
    creator_avatar?: string
  }
  hideDate?: boolean
  disableSwipe?: boolean
  /** 是否显示创建者信息（群组模式） */
  showCreator?: boolean
  /** 当前用户 ID，用于判断是否为本人记录 */
  currentUserId?: number
  /** 是否显示左滑提示动画（由父组件控制，仅首个可删除项传入true） */
  swipeHint?: boolean
}>(), { hideDate: false, disableSwipe: false, showCreator: false, currentUserId: 0, swipeHint: false })

/** 是否为他人的记录（群组模式下，非本人的才显示创建者信息） */
const isOtherCreator = computed(() => {
  if (!props.showCreator || !props.item.creator_nickname) return false
  return !props.currentUserId || props.item.user_id !== props.currentUserId
})

defineEmits(['item-tap', 'delete'])

const creatorAvatarUrl = computed(() => {
  if (!props.item.creator_avatar) return ''
  if (props.item.creator_avatar.startsWith('http') || props.item.creator_avatar.startsWith('blob:')) return props.item.creator_avatar
  // 截取服务端根地址（去掉 /api）
  const base = API_BASE.replace(/\/api$/, '')
  return base + '/api/user/avatar/' + props.item.creator_avatar
})

const startX = ref(0)
const offsetX = ref(0)
const showDelete = ref(false)

function onTouchStart(e: any) {
  startX.value = e.touches[0].clientX
}

function onTouchMove(e: any) {
  const diff = e.touches[0].clientX - startX.value
  if (diff < 0) {
    offsetX.value = Math.max(diff * 2, -160)
  } else if (showDelete.value) {
    offsetX.value = Math.min(diff * 2 - 160, 0)
  }
}

function onTouchEnd() {
  if (offsetX.value < -80) {
    offsetX.value = -160
    showDelete.value = true
  } else {
    offsetX.value = 0
    showDelete.value = false
  }
}
</script>

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

.tx-item-wrap {
  position: relative;
  overflow: hidden;
  margin-bottom: 8rpx;
}

.tx-item {
  display: flex;
  align-items: center;
  padding: 28rpx 24rpx;
  gap: 24rpx;
  border-radius: 20rpx;
  transition: transform 0.2s ease;
  background: $surface;
  position: relative;
  z-index: 1;

  &:active {
    background: $surface-warm;
  }
}

// 左滑提示：仅在 swipeHint=true 且 disableSwipe=false 时播放一次
.show-hint .tx-item {
  animation: swipe-hint 0.6s ease 1.5s both;
}

@keyframes swipe-hint {
  0% { transform: translateX(0); }
  40% { transform: translateX(-40rpx); }
  100% { transform: translateX(0); }
}

.delete-btn {
  position: absolute;
  right: 0;
  top: 0;
  bottom: 0;
  width: 160rpx;
  background: $danger;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 0 20rpx 20rpx 0;
  opacity: 0;
  transition: opacity 0.2s ease;
  z-index: 0;

  &.visible {
    opacity: 1;
  }
}

.creator-tag {
  margin-right: 4rpx;
  display: inline;
}

.creator-mini-avatar {
  width: 28rpx;
  height: 28rpx;
  border-radius: 50%;
  margin-right: 4rpx;
  position: relative;
  top: 4rpx;
}

.creator-mini-initial {
  display: flex;
  width: 28rpx;
  height: 28rpx;
  border-radius: 50%;
  background: $primary-light;
  font-size: 16rpx;
  color: $primary;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.info {
  flex: 1;
  min-width: 0;
}

.name {
  font-size: 28rpx;
  font-weight: 500;
  color: $text;
  display: block;
  @include text-ellipsis;
}

.meta {
  font-size: 24rpx;
  color: $text-sec;
  display: block;
  margin-top: 4rpx;
}

.creator-name {
  color: $primary;
  font-weight: 500;
}

.amount {
  font-family: 'Fredoka', sans-serif;
  font-size: 32rpx;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;

  &.expense { color: $text; }
  &.income { color: $success; }
}

@media (prefers-reduced-motion: reduce) {
  .show-hint .tx-item {
    animation: none;
  }
}
</style>
