<script setup lang="ts">
import {
  appMerchantOrderOrderListPost,
  type MerchantOrderVo
} from "@/service";
import {callPhone} from "@/utils/utils";
import {OrderCancelStatus, OrderStatus} from "@/constant/enums";
import {useUserStore} from "@/store";
import {dayjs} from "@/plugin";

const userStore = useUserStore();
const { t } = useI18n();
const props = defineProps<{
  currentIndex: number
  status: null | number | string
}>()

watch(() => props.currentIndex, (newVal, oldVal) => {
  if (newVal === props.status && !firstLoaded.value) {
    paging.value?.refresh()
  }
}, {
  deep: true,
})

const {paging, dataList, loading, queryList, firstLoaded} = usePage<MerchantOrderVo[]>((pageNum, pageSize)=>{
  if(userStore.isLogin) {
    return appMerchantOrderOrderListPost({
      params: {
        pageNum,
        pageSize,
      },
      body: {
        userPort: 1,
        orderStatusList: props.status !== null && props.status !== '' ? [Number(props.status)] : [],
      }
    })
  } else {
    return new Promise(resolve => {
      resolve([])
    })
  }
})

function normalizeTimestamp(input: unknown): number | null {
  if (input == null || input === '') return null

  let value: number
  if (typeof input === 'string') {
    const trimmed = input.trim()
    if (!trimmed) return null
    value = Number(trimmed)
  } else {
    value = Number(input)
  }

  if (!Number.isFinite(value) || value <= 0) return null

  // 兼容后端可能返回秒级时间戳
  if (value < 1e12) {
    value = value * 1000
  }
  return value
}

function formatOrderCardTime(item: MerchantOrderVo) {
  // 优先使用下单时间 createTime；没有则回退到预约结束时间
  const ts = normalizeTimestamp((item as any)?.createTime ?? item?.endScheduledTime)
  if (!ts) return '--'
  return dayjs(ts).format('YYYY/MM/DD HH:mm')
}

function formatOrderPrice(item: MerchantOrderVo) {
  const raw = item?.paidAmount ?? item?.actualPrice ?? 0
  if (raw == null || raw === '') return '0.00'
  if (typeof raw === 'number') return raw.toFixed(2)
  const str = String(raw).trim()
  if (!str) return '0.00'
  if (!str.includes('.')) return `${str}.00`
  const [intPart, decimalPart = ''] = str.split('.')
  return `${intPart}.${(decimalPart + '00').slice(0, 2)}`
}

function getOrderDishes(item: MerchantOrderVo): Array<Record<string, any>> {
  const list = item.merchantOrderDishVoList as unknown as Array<Record<string, any>> | null | undefined
  if (!list || !Array.isArray(list)) return []
  return list
}

function dishCover(dish: Record<string, any>) {
  const img = dish?.merchantDishVo?.dishImage
  if (!img || typeof img !== 'string') return ''
  return img.split(',')[0] || ''
}

function dishTitle(dish: Record<string, any>) {
  return dish?.merchantDishVo?.dishName ?? ''
}

function getTotalDishCount(item: MerchantOrderVo) {
  return getOrderDishes(item).reduce((s, d) => s + (d.count || 0), 0)
}

function getTotalDishCountText(item: MerchantOrderVo) {
  return t('pages.order.totalItemCount', {
    count: getTotalDishCount(item),
  })
}

function isSameCode(value: unknown, code: unknown) {
  return String(value ?? '') === String(code ?? '')
}

function isRefundApplied(item: MerchantOrderVo) {
  return isSameCode(item.refundStatus, OrderCancelStatus.APPLIED)
}

function isRefundApproved(item: MerchantOrderVo) {
  return isSameCode(item.refundStatus, OrderCancelStatus.APPROVED)
}

function isRefundRejected(item: MerchantOrderVo) {
  return isSameCode(item.refundStatus, OrderCancelStatus.REJECTED)
}

function getOrderStatusText(item: MerchantOrderVo) {
  if (isRefundApplied(item)) return t('pages-store.order.orderStatus.refund')
  if (isRefundApproved(item)) return t('pages-store.order.orderStatus.agreeRefund')
  if (isRefundRejected(item)) return t('pages-store.order.orderStatus.rejectRefund')
  if (isSameCode(item.orderStatus, OrderStatus.CANCELLED)) return t('pages-store.order.orderStatus.cancelled')
  if (isSameCode(item.orderStatus, OrderStatus.PENDING_PAYMENT)) return t('pages-store.order.orderStatus.pendingPayment')
  if (isSameCode(item.orderStatus, OrderStatus.HAS_PENDING_PAYMENT)) return t('pages-store.order.orderStatus.hasPendingPayment')
  if (isSameCode(item.orderStatus, OrderStatus.MERCHANT_ACCEPTED)) return t('pages-store.order.orderStatus.received')
  if (isSameCode(item.receiveMethod, 1) && isSameCode(item.orderStatus, OrderStatus.DELIVERING)) return t('pages-store.order.orderStatus.delivering')
  if (isSameCode(item.orderStatus, OrderStatus.COMPLETED)) return t('pages-store.order.orderStatus.delivered')
  if (isSameCode(item.orderStatus, OrderStatus.MERCHANT_REJECTED)) return t('pages-store.store.orderStatus.rejected')
  return '--'
}

function handleClick(item: MerchantOrderVo) {
  uni.navigateTo({
    url: '/pages-store/pages/order/index?id=' + item.id
  })
}

function handleCancelClick(item: MerchantOrderVo) {
  uni.navigateTo({
    url: '/pages-store/pages/order/index?id=' + item.id
  })
}

function reload() {
  paging.value?.reload()
}

function refresh() {
  paging.value?.refresh()
}

defineOptions({
  name: 'OrderSwiperList',
})

defineExpose({
  reload,
  refresh,
})
</script>

<template>
  <view class="list-root h-full">
    <z-paging ref="paging" v-model="dataList" @query="queryList" :fixed="false" :auto="false">
      <view class="page-pad">
        <view
            v-show="loading"
            class="animate-in fade-in animate-ease-out animate-duration-300"
        >
          <view v-for="sk in 3" :key="'sk-' + sk" class="order-card order-card--skeleton mb-24rpx">
              <view class="flex-center-sb mb-24rpx">
                <view class="w-280rpx h-32rpx skeleton-item rounded-8rpx"></view>
                <view class="w-120rpx h-32rpx skeleton-item rounded-8rpx"></view>
              </view>
              <view class="flex items-center mb-24rpx">
                <view class="w-32rpx h-32rpx skeleton-item rounded-6rpx mr-10rpx"></view>
                <view class="w-240rpx h-28rpx skeleton-item rounded-6rpx"></view>
                <view class="w-72rpx h-28rpx skeleton-item rounded-20rpx ml-16rpx"></view>
              </view>
              <view class="flex gap-16rpx mb-24rpx">
                <view v-for="i in 3" :key="i" class="sk-thumb">
                  <view class="sk-thumb-img skeleton-item"></view>
                  <view class="w-100rpx h-22rpx skeleton-item rounded-4rpx mt-10rpx"></view>
                </view>
                <view class="flex-1"></view>
                <view class="w-100rpx flex flex-col items-end gap-12rpx pt-8rpx">
                  <view class="w-88rpx h-30rpx skeleton-item rounded-4rpx"></view>
                  <view class="w-72rpx h-22rpx skeleton-item rounded-4rpx"></view>
                </view>
              </view>
              <view class="flex justify-end">
                <view class="sk-pill skeleton-item"></view>
              </view>
          </view>
        </view>
        <view
            class="animate-in fade-in animate-ease-in animate-duration-300"
            v-if="!loading"
        >
          <view
              v-for="(item,index) in dataList"
              :key="item.id"
              :class="[index === 0 ? '' : 'mt-24rpx']"
              class="order-card"
              @click="handleClick(item)"
          >
              <view class="flex-center-sb items-start gap-16rpx">
                <text class="order-time">{{ formatOrderCardTime(item) }}</text>
                <text class="order-status shrink-0" :class="{ 'text-#FF6106': isSameCode(item.orderStatus, OrderStatus.MERCHANT_REJECTED) }">
                  {{ getOrderStatusText(item) }}
                </text>
              </view>

              <view class="store-row">
                <image src="@img/chef/126.png" class="store-icon" mode="aspectFit"></image>
                <text class="store-name line-clamp-1">{{ item.merchantVo?.merchantName }}</text>
                <view v-if="isSameCode(item.receiveMethod, 1)" class="recv-tag recv-tag--del">
                  {{ t('pages.order.DEL') }}
                </view>
                <view v-if="isSameCode(item.receiveMethod, 2)" class="recv-tag recv-tag--pu">
                  {{ t('pages.order.PU') }}
                </view>
              </view>

              <view class="goods-row">
                <scroll-view scroll-x class="goods-scroll" :show-scrollbar="false" :enable-flex="true">
                  <view class="goods-track">
                    <view
                        v-for="(dish, di) in getOrderDishes(item)"
                        :key="dish.id ?? di"
                        class="goods-cell"
                    >
                      <view class="goods-img-wrap">
                        <image
                            :src="dishCover(dish)"
                            mode="aspectFill"
                            class="goods-img"
                        />
                        <view
                            v-if="dish.count > 1"
                            class="goods-qty"
                        >x{{ dish.count }}</view>
                      </view>
                      <text class="goods-caption">{{ dishTitle(dish) }}</text>
                    </view>
                  </view>
                </scroll-view>
                <view class="price-block shrink-0">
                  <text class="price-num">${{ formatOrderPrice(item) }}</text>
                  <text class="price-meta">{{ getTotalDishCountText(item) }}</text>
                </view>
              </view>

              <view class="action-row" @click.stop>
                <view class="action-left">
                  <image
                      v-if="isSameCode(item.receiveMethod, 2) && isSameCode(item.orderStatus, OrderStatus.MERCHANT_ACCEPTED)"
                      src="@img/chef/127.png"
                      class="action-icon"
                  />
                  <image
                      v-if="!isSameCode(item.orderStatus, OrderStatus.PENDING_PAYMENT) && !isSameCode(item.orderStatus, OrderStatus.CANCELLED) && isSameCode(item.receiveMethod, 1)"
                      src="@img/chef/128.png"
                      class="action-icon"
                      @click="callPhone(item.merchantVo?.phone)"
                  />
                </view>
                <view class="action-btns">
                  <template v-if="!isRefundApplied(item) && !isRefundApproved(item)">
                    <view
                        v-if="!isSameCode(item.orderStatus, OrderStatus.CANCELLED) && !isSameCode(item.orderStatus, OrderStatus.COMPLETED) && !isSameCode(item.orderStatus, OrderStatus.MERCHANT_REJECTED)"
                        class="btn-outline"
                        @click="handleCancelClick(item)"
                    >{{ t('pages.order.cancelOrder') }}</view>
                    <view
                        v-if="isSameCode(item.receiveMethod, 2) && isSameCode(item.orderStatus, OrderStatus.MERCHANT_ACCEPTED)"
                        class="btn-primary"
                        @click="handleClick(item)"
                    >{{ t('pages-store.order.writeOff') }}</view>
                    <view
                        v-if="isSameCode(item.orderStatus, OrderStatus.COMPLETED) && item?.dishReviewVoList?.length === 0"
                        class="btn-primary"
                        @click="handleClick(item)"
                    >{{ t('common.evaluate') }}</view>
                  </template>
                </view>
              </view>
          </view>
        </view>
      </view>
    </z-paging>
  </view>
</template>

<style scoped lang="scss">
.list-root {
  background: #F5F5F5;
}

.page-pad {
  padding: 24rpx 24rpx 32rpx;
}

.order-card {
  background: #fff;
  border-radius: 24rpx;
  padding: 28rpx 24rpx 24rpx;
  box-shadow: 0 2rpx 16rpx rgba(0, 0, 0, 0.04);
}

.order-card--skeleton {
  box-shadow: none;
}

.order-time {
  font-size: 28rpx;
  line-height: 36rpx;
  color: #14181B;
  font-weight: 500;
}

.order-status {
  font-size: 28rpx;
  line-height: 36rpx;
  color: #00A76D;
  font-weight: 500;
}

.store-row {
  display: flex;
  align-items: center;
  margin-top: 20rpx;
  gap: 0;
}

.store-icon {
  width: 32rpx;
  height: 32rpx;
  margin-right: 10rpx;
  flex-shrink: 0;
}

.store-name {
  flex: 1;
  min-width: 0;
  font-size: 28rpx;
  line-height: 36rpx;
  color: #14181B;
  font-weight: 500;
}

.recv-tag {
  flex-shrink: 0;
  margin-left: 16rpx;
  padding: 4rpx 14rpx;
  border-radius: 8rpx;
  font-size: 22rpx;
  line-height: 28rpx;
  color: #fff;
  font-weight: 500;
}

.recv-tag--del {
  background: #FF6106;
}

.recv-tag--pu {
  background: #00A76D;
}

.goods-row {
  display: flex;
  align-items: flex-start;
  margin-top: 24rpx;
  gap: 16rpx;
}

.goods-scroll {
  flex: 1;
  min-width: 0;
  align-self: flex-start;
  height: auto;
}

.goods-track {
  display: flex;
  flex-direction: row;
  gap: 16rpx;
  padding-right: 8rpx;
}

.goods-cell {
  width: 128rpx;
  flex-shrink: 0;
}

.goods-img-wrap {
  position: relative;
  width: 128rpx;
  height: 128rpx;
  border-radius: 16rpx;
  overflow: hidden;
  background: #F2F2F2;
}

.goods-img {
  width: 100%;
  height: 100%;
}

.goods-qty {
  position: absolute;
  right: 6rpx;
  bottom: 6rpx;
  min-width: 36rpx;
  padding: 4rpx 10rpx;
  background: rgba(20, 24, 27, 0.85);
  color: #fff;
  font-size: 20rpx;
  line-height: 24rpx;
  border-radius: 8rpx;
  text-align: center;
}

.goods-caption {
  display: block;
  margin-top: 10rpx;
  font-size: 22rpx;
  line-height: 28rpx;
  color: #333;
  min-height: 56rpx;
  overflow: hidden;
  text-overflow: ellipsis;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  word-break: break-word;
}

.price-block {
  text-align: right;
  padding-top: 8rpx;
  max-width: 200rpx;
}

.price-num {
  display: block;
  font-size: 32rpx;
  line-height: 40rpx;
  font-weight: 700;
  color: #14181B;
}

.price-meta {
  display: block;
  margin-top: 8rpx;
  font-size: 22rpx;
  line-height: 28rpx;
  color: #999;
}

.action-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-top: 24rpx;
}

.action-left {
  display: flex;
  align-items: center;
  gap: 16rpx;
}

.action-icon {
  width: 56rpx;
  height: 56rpx;
}

.action-btns {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 16rpx;
  flex-wrap: wrap;
}

.btn-outline {
  padding: 16rpx 32rpx;
  border-radius: 999rpx;
  border: 2rpx solid #14181B;
  font-size: 26rpx;
  font-weight: 500;
  color: #14181B;
  background: #fff;
  line-height: 32rpx;
}

.btn-primary {
  padding: 16rpx 32rpx;
  border-radius: 999rpx;
  background: #14181B;
  font-size: 26rpx;
  font-weight: 500;
  color: #fff;
  line-height: 32rpx;
}

.sk-thumb {
  flex-shrink: 0;
  width: 128rpx;
}

.sk-thumb-img {
  width: 128rpx;
  height: 128rpx;
  border-radius: 16rpx;
}

.sk-pill {
  width: 176rpx;
  height: 60rpx;
  border-radius: 9999rpx;
}
</style>
