<template>
  <cwg-load-more-wrapper ref="loadMoreWrapperRef" :loading="loading" :finished="finished" :height='108'
    :refresher-enabled="pageSize != 4" @reach-bottom="loadMore" @refresh="handleRefresh">
    <view v-if="records.length > 0" :class="{
      'records-list': true,
      'records-list1': pageSize === 4
    }">
      <view v-for="record in records" :key="record.id" class="record-card" @click="goToTransactionDetail(record)">
        <view class="record-main">
          <view class="record-left">
            <view class="type-icon transaction-icon">
              <cwg-icon class="icons" :name="getTransactionIcon(record.type)" :size="20" color="#2563eb" />
            </view>
            <view class="record-info">
              <view class="info-header">
                <text class="record-type">{{ getTransactionTypeText(record.type) }}</text>
                <view :class="['status-badge', getStatusBadgeClass(record.status)]">
                  <cwg-icon class="icons" :name="getStatusIcon(record.status)" :size="12"
                    :color="getStatusColor(record.status)" />
                  <text :class="['status-text', getStatusTextClass(record.status)]">
                    {{ getStatusText(record.status) }}
                  </text>
                </view>
              </view>
              <text class="record-detail">{{ record.remark || record.merchant || '--' }}</text>
            </view>
          </view>

          <view class="record-right">
            <text class="amount-transaction">{{ Number(record.amount || 0) >= 0 ? '+' : '-' }}{{
              Math.abs(Number(record.amount || 0)).toFixed(2) }} {{ record.currency || 'USD' }}</text>
            <text class="fee-text">{{ t('global.p17') }} {{ Number(record.fee || 0).toFixed(2) }}</text>
          </view>
        </view>

        <view class="record-footer">
          <text class="footer-time">{{ formatDateTime(record.transactionTime) }}</text>
          <view class="footer-actions">
            <text class="footer-order">
              {{ t('global.p15') }}: {{ formatOrderNo(record.tradeNo) }}
            </text>
            <cwg-icon class="footer-order-icon" name="copy" :size="14" color="#9ca3af"
              @click.stop="copyOrderNo(record.tradeNo)" />
          </view>
        </view>
      </view>
    </view>
    <cwg-empty-state v-else />
  </cwg-load-more-wrapper>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted } from 'vue';
import dayjs from 'dayjs';
import { useI18n } from 'vue-i18n';
import { showToast } from '@/utils/toast';
import { ucardApi, TransactionInfo } from '@/api/ucard';
import { transactionTypeMap, transactionStatusMap } from '@/utils/dataMap';
import useCardStore from '@/stores/use-card-store';

interface RecordItem extends TransactionInfo {
  type?: string;
  typeStr?: string;
  remark?: string;
  status?: string | number;
  transactionTime?: string | number;
  fee?: number;
  currency?: string;
  tradeNo?: string;
  merchant?: string;
}

type NormalizedStatus = 'success' | 'processing' | 'failed';

const props = defineProps<{
  cardNumber: string;
  pageSize: number;
  typeIndex: number;
  statusIndex: number;
  dateFilter: string;
  typeOptions: string[];
}>();

const { t } = useI18n();

const records = ref<RecordItem[]>([]);
const page = ref(1);
const pageSize = computed(() => props.pageSize || 10);
const loading = ref(false);
const finished = ref(false);

const cardStore = useCardStore();

const normalizeStatus = (status?: string | number): NormalizedStatus => {
  if (!status) return 'success';
  const statusStr = String(status).toLowerCase();
  if (statusStr === 'processing' || statusStr === 'wait_process') return 'processing';
  if (statusStr === 'fail' || statusStr === 'failed') return 'failed';
  if (statusStr === 'succeed' || statusStr === 'success') return 'success';
  return 'success';
};

const getStatusText = (status?: string | number): string => {
  if (!status) return '';
  const statusKey = String(status).toLowerCase();
  if (transactionStatusMap[statusKey as keyof typeof transactionStatusMap]) {
    return t(transactionStatusMap[statusKey as keyof typeof transactionStatusMap]);
  }
  const normalized = normalizeStatus(status);
  if (normalized === 'success') return t('card.Status.t1');
  if (normalized === 'processing') return t('card.Status.t3');
  return t('card.Status.t2');
};

const getStatusIcon = (status?: string | number): string => {
  const normalized = normalizeStatus(status);
  if (normalized === 'success') return 'checkmarkempty1';
  if (normalized === 'processing') return 'info1';
  return 'closeempty1';
};

const getStatusColor = (status?: string | number): string => {
  const normalized = normalizeStatus(status);
  if (normalized === 'success') return '#22c55e';
  if (normalized === 'processing') return '#eab308';
  return '#ef4444';
};

const getStatusBadgeClass = (status?: string | number) => `status-${normalizeStatus(status)}`;
const getStatusTextClass = (status?: string | number) => `status-text-${normalizeStatus(status)}`;

const getStatusValue = (index: number): NormalizedStatus | null => {
  if (index === 0) return null;
  const statusMap: NormalizedStatus[] = ['success', 'processing', 'failed'];
  return statusMap[index - 1];
};

const getTransactionTypeText = (type?: string): string => {
  if (!type) return '--';
  const key = type.toLowerCase();
  if (transactionTypeMap[key as keyof typeof transactionTypeMap]) {
    return t(transactionTypeMap[key as keyof typeof transactionTypeMap]);
  }
  return type;
};

const getTransactionIcon = (type = ''): string => {
  if (type.includes('购买') || type === 'refund') return 'cart';
  if (type.includes('提现') || type === 'auth') return 'minus-filled';
  if (type.includes('转账')) return 'redo';
  if (type.includes('话费')) return 'phone';
  if (type.includes('缴费')) return 'flame';
  if (type === 'maintain_fee') return 'servicefee';
  return 'servicefee';
};

const formatDateTime = (time?: string | number): string => {
  if (!time) return '--';
  try {
    let date: dayjs.Dayjs;
    if (typeof time === 'number') {
      if (time.toString().length === 10) {
        date = dayjs.unix(time);
      } else {
        date = dayjs(time);
      }
    } else {
      date = dayjs(time);
    }
    if (!date.isValid()) return '--';
    return date.format('YYYY-MM-DD HH:mm:ss');
  } catch (error) {
    return '--';
  }
};

const getDatePart = (time?: string | number): string => {
  if (!time) return '';
  try {
    let date: dayjs.Dayjs;
    if (typeof time === 'number') {
      if (time.toString().length === 10) {
        date = dayjs.unix(time);
      } else {
        date = dayjs(time);
      }
    } else {
      date = dayjs(time);
    }
    if (!date.isValid()) return '';
    return date.format('YYYY-MM-DD');
  } catch (error) {
    return '';
  }
};

const formatOrderNo = (orderNo?: string) => {
  if (!orderNo) return '--';
  if (orderNo.length <= 20) return orderNo;
  return orderNo.slice(0, 6) + '...' + orderNo.slice(-4);
};

const copyOrderNo = (orderNo?: string) => {
  if (!orderNo) return;
  uni.setClipboardData({
    data: orderNo,
    success: () => {
      uni.showToast({
        title: t('card.Msg.m8') || '复制成功',
        icon: 'success'
      });
    }
  });
};

const fetchRecords = async (isLoadMore = false) => {
  if (!props.cardNumber || loading.value) return;
  if (isLoadMore && finished.value) return;

  loading.value = true;
  try {
    const res = await ucardApi.transactionsList({
      cardNumber: props.cardNumber,
      type: props.typeIndex == -1 ? undefined : props.typeIndex,
      status: props.statusIndex == -1 ? undefined : props.statusIndex,
        beginDate: props.dateFilter?.[0] ? dayjs(props.dateFilter[0]).format('YYYY-MM-DD') : undefined,
        endDate: props.dateFilter?.[1] ? dayjs(props.dateFilter[1]).format('YYYY-MM-DD') : undefined,
      page: { current: page.value, row: pageSize.value },
    });
    const data = res.code === 200 && Array.isArray(res.data) ? res.data : [];

    if (isLoadMore) {
      records.value.push(...data);
    } else {
      records.value = data;
    }

    if (data.length < pageSize.value) {
      finished.value = true;
    } else {
      finished.value = false;
    }
  } catch (error: any) {
    if (!isLoadMore) {
      records.value = [];
    }
    showToast(error?.message || String(error));
  } finally {
    loading.value = false;
  }
};

const goToTransactionDetail = (record: RecordItem) => {
  const amount = Number(record.amount || 0);
  const fee = Number(record.fee || 0);
  const normalizedStatus = normalizeStatus(record.status);

  const detailPayload = {
    category: 'transaction' as const,
    orderNo: record.tradeNo || '',
    type: getTransactionTypeText(record.type),
    amount,
    fee,
    actualAmount: amount - fee,
    currency: record.currency || 'USD',
    orderStatus: normalizedStatus,
    statusMessage: getStatusText(record.status),
    createTime: formatDateTime(record.transactionTime),
    completeTime: '',
    merchant: record.merchant || '',
    bankCard: '',
    remark: record.remark || '',
    approvalSteps: [] as any[]
  };

  cardStore.saveOrderDetail(detailPayload);
  uni.navigateTo({
    url: '/pages/recharge-record/detail'
  });
};

const loadMore = () => {
  if (finished.value || loading.value || props.pageSize == 4) return;
  page.value++;
  fetchRecords(true);
};


watch([() => props.dateFilter], () => {
  page.value = 1;
  finished.value = false;
  fetchRecords();
}, { immediate: false });
watch([() => props.typeIndex], () => {
  page.value = 1;
  finished.value = false;
  fetchRecords();
}, { immediate: false });
watch([() => props.statusIndex], () => {
  page.value = 1;
  finished.value = false;
  fetchRecords();
}, { immediate: false });
watch([() => props.cardNumber], () => {
  page.value = 1;
  finished.value = false;
  fetchRecords();
}, { immediate: false });
const loadMoreWrapperRef = ref<any>(null);

const refresh = async () => {
  page.value = 1;
  finished.value = false;
  await fetchRecords();
};

const handleRefresh = async () => {
  await refresh();
  // 停止下拉刷新动画
  if (loadMoreWrapperRef.value) {
    loadMoreWrapperRef.value.stopRefresh();
  }
};

onMounted(() => {
  fetchRecords();
});

defineExpose({
  refresh
});
</script>

<style scoped lang="scss">
@import "@/uni.scss";

.records-list {
  display: flex;
  flex-direction: column;
  gap: px2rpx(12);
  padding: px2rpx(16);
}

.records-list1 {
  flex-direction: row;
  flex-wrap: wrap;
  gap: px2rpx(12);
  padding: px2rpx(16) 0;
}

.record-card {
  background-color: #ffffff;
  border-radius: px2rpx(12);
  border: 1px solid #e5e7eb;
  overflow: hidden;
  transition: box-shadow 0.3s;
  padding: px2rpx(16);
}

.record-card:active {
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
}

.record-main {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  padding-bottom: px2rpx(16);
}

.record-left {
  display: flex;
  align-items: flex-start;
  gap: px2rpx(12);
  flex: 1;
  min-width: 0;
}

.type-icon {
  width: px2rpx(40);
  height: px2rpx(40);
  border-radius: px2rpx(10);
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}

.transaction-icon {
  background-color: #eff6ff;
}

.icons {
  width: px2rpx(20);
  height: px2rpx(20);
}

.record-info {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: px2rpx(6);
}

.info-header {
  display: flex;
  align-items: center;
  gap: px2rpx(8);
  flex-wrap: wrap;
}

.record-type {
  font-size: px2rpx(15);
  color: #111827;
}

.status-success {
  background-color: #f0fdf4;
}

.status-processing {
  background-color: #fefce8;
}

.status-failed {
  background-color: #fef2f2;
}

.status-text {
  font-size: px2rpx(11);
}

.status-text-success {
  color: #22c55e;
}

.status-text-processing {
  color: #eab308;
}

.status-text-failed {
  color: #ef4444;
}

.record-detail {
  font-size: px2rpx(13);
  color: #6b7280;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.record-right {
  display: flex;
  flex-direction: column;
  align-items: flex-end;
  gap: px2rpx(4);
  margin-left: px2rpx(12);
  flex-shrink: 0;
}

.amount-transaction {
  font-size: px2rpx(18);
  color: #111827;
}

.fee-text {
  font-size: px2rpx(11);
  color: #9ca3af;
}

.record-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-top: px2rpx(16);
  border-top: 1px solid #f3f4f6;
}

.footer-actions {
  display: flex;
  align-items: center;
  gap: px2rpx(8);
}

.footer-time {
  font-size: px2rpx(11);
  color: #9ca3af;
}

.footer-actions {
  display: flex;
  align-items: center;
  gap: px2rpx(2);
}

.footer-order {
  font-size: px2rpx(11);
  color: #9ca3af;
}

.footer-detail {
  font-size: px2rpx(11);
  color: #2563eb;
}
</style>
