package com.qnfhq.modules.c2c.controller;


import cn.dev33.satoken.stp.StpUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.qnfhq.annotation.RepeatSubmit;
import com.qnfhq.common.ApiBaseController;
import com.qnfhq.common.constant.Constant;
import com.qnfhq.common.exception.ErrorCode;
import com.qnfhq.common.page.PageData;
import com.qnfhq.common.redis.RedisUtils;
import com.qnfhq.common.utils.DateUtils;
import com.qnfhq.common.utils.MessageUtils;
import com.qnfhq.common.utils.Result;
import com.qnfhq.common.validator.ValidatorUtils;
import com.qnfhq.constant.CacheConstants;
import com.qnfhq.modules.c2c.dto.*;
import com.qnfhq.modules.c2c.entity.*;
import com.qnfhq.modules.c2c.enums.AdStatusEnum;
import com.qnfhq.modules.c2c.enums.C2cOrderFlowEnum;
import com.qnfhq.modules.c2c.enums.C2cOrderStatusEnum;
import com.qnfhq.modules.c2c.enums.DirectionEnum;
import com.qnfhq.modules.c2c.service.*;
import com.qnfhq.modules.user.entity.AppAssetEntity;
import com.qnfhq.modules.user.entity.AppUserDetailEntity;
import com.qnfhq.modules.user.entity.AppUserEntity;
import com.qnfhq.modules.user.enums.AssetEnum;
import com.qnfhq.modules.user.enums.AuditStatusEnum;
import com.qnfhq.modules.user.service.AppAssetService;
import com.qnfhq.modules.user.service.AppUserDetailService;
import com.qnfhq.modules.user.service.AppUserService;
import com.qnfhq.utils.DistributedRedisLock;
import io.swagger.v3.oas.annotations.Operation;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import io.swagger.v3.oas.annotations.tags.Tag;

/**
 * c2c订单
 *
 * @author yelz 30262728@qq.com
 * @since 1.0.0 2025-11-17
 */
@Slf4j
@RestController
@RequestMapping("/c2corder")
@Tag(name="c2c订单")
public class C2cOrderController extends ApiBaseController {
    private final static String LOCK_C2C_ORDER = "lock_c2c_order";
    private final static String LOCK_C2C_AD = "lock_c2c_ad:";

    @Resource
    private C2cOrderService c2cOrderService;

    @Resource
    private AppUserDetailService appUserDetailService;

    @Resource
    private AppAssetService appAssetService;

    @Resource
    private C2cAdService c2cAdService;

    @Resource
    private C2cPaymentVoucherService c2cPaymentVoucherService;

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private DistributedRedisLock distributedRedisLock;

    @Resource
    private C2cUserReceiptService c2cUserReceiptService;

    @Resource
    private C2cOrderComplainService orderComplainService;

    @Resource
    private C2cOrderComplainVoucherService orderComplainVoucherService;
    @Resource
    private AppUserService appUserService;
    @Resource
    private C2cMerchantService c2cMerchantService;


    private String getC2cAdLockKey(String adId) {
        return new StringBuilder(LOCK_C2C_AD).append(adId).toString();
    }

    private String getC2cOrderLockKey(String oId) {
        return new StringBuilder(LOCK_C2C_ORDER).append(oId).toString();
    }

    @Operation(summary = "c2c下单")
    @PostMapping("/create")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result create(@RequestBody C2cOrderCreateDTO c2cOrder) {
        Result result = new Result();
        ValidatorUtils.validateEntity(c2cOrder);

        //进行中的订单
        String odUserKey = c2cOrderService.getC2cOrderKeyByUid(StpUtil.getLoginIdAsString());//c2c_order_uid:1
        String orderId = (String)redisUtils.get(odUserKey);
        if(StrUtil.isNotBlank(orderId)) {
            C2cOrderEntity order = c2cOrderService.selectOrder(Long.valueOf(orderId));
            if(order == null) {//订单编号无效
                c2cOrderService.deleteOrderCache(orderId, StpUtil.getLoginIdAsString());
            } else {
                if(order.getFlow().intValue() == C2cOrderFlowEnum.PROGRESS.getCode().intValue()) {
                    return result.error(ErrorCode.C2C_ORDER_PROCESS, MessageUtils.message("c2c.order.create.tran.fail"));//您有一笔正在进行中的交易，请先处理。处理完成后，可继续交易。
                } else {
                    c2cOrderService.deleteOrderCache(orderId, StpUtil.getLoginIdAsString());
                }
            }
        }

        Integer direction = c2cOrder.getDirection();
        if(!DirectionEnum.isValidCode(direction.intValue())) {
            return result.error(MessageUtils.message("merchant.param.direction.invalid"));//参数direction值不正确
        }


        //实名认证
        long loginUserId = StpUtil.getLoginIdAsLong();
        AppUserDetailEntity appUserDetail = appUserDetailService.selectAppUserDetailByUserId(loginUserId);
        if(appUserDetail==null || appUserDetail.getAuditStatus().intValue() != AuditStatusEnum.EXAMINATION_PASSED.getCode().intValue()) {
            return result.error(ErrorCode.SHIMING_VERIFY,MessageUtils.message("user.authentication.not.certified"));//请先进行实名认证
        }

        C2cAdEntity c2cAd = c2cAdService.selectById(c2cOrder.getC2cAdId());
        if(c2cAd==null) {
            //清除缓存
            Integer adDirection = direction.intValue() == DirectionEnum.SELL.getCode().intValue() ? DirectionEnum.BUY.getCode() : DirectionEnum.SELL.getCode();
            c2cAdService.deleteAdCache(c2cOrder.getC2cAdId(), c2cOrder.getPayType().toString(), c2cOrder.getLegalCoin(), c2cOrder.getSymbol(), adDirection);
            return error(MessageUtils.message("c2c.order.param.adid"));//广告编号无效
        }
        if(c2cAd.getStatus().intValue()== AdStatusEnum.NOPASS.getCode()) {
            //清除缓存
            Integer adDirection = c2cAd.getDirection();
            String adLegalCoin = c2cAd.getLegalCoin();
            String adSymbol = c2cAd.getSymbol();
            String adPayway = c2cAd.getPayway().replaceAll("^,|,$", "");
            c2cAdService.deleteAdCache(c2cAd.getId(), adPayway, adLegalCoin, adSymbol, adDirection);
            return error(MessageUtils.message("c2c.order.param.adid.invalid"));//广告已不可用
        }

        BigDecimal availableNum = c2cAd.getAvailableNum();
        BigDecimal minAmount = c2cAd.getMinAmount();
        BigDecimal maxAmount = c2cAd.getMaxAmount();
        BigDecimal price = c2cAd.getPrice();

        //数币金额
        String unit = c2cOrder.getUnit().toLowerCase();
        String symbol = c2cOrder.getSymbol().toLowerCase();
        BigDecimal symbolAmount = BigDecimal.ZERO;
        BigDecimal legalCoinAmount = BigDecimal.ZERO;
        if(unit.equals(symbol)) {
            symbolAmount = c2cOrder.getTranAmount();
            legalCoinAmount = symbolAmount.multiply(price).setScale(2, RoundingMode.DOWN);
        } else {
            symbolAmount = c2cOrder.getTranAmount().divide(price).setScale(8, RoundingMode.DOWN);
            legalCoinAmount = c2cOrder.getTranAmount().setScale(2, RoundingMode.DOWN);
        }
        //卖出检查资产
        if(direction.intValue() == DirectionEnum.SELL.getCode().intValue()) {
            AppAssetEntity tAppAsset = new AppAssetEntity();
            tAppAsset.setUserId(loginUserId);
            tAppAsset.setSymbol(c2cOrder.getSymbol());
            tAppAsset.setType(AssetEnum.PLATFORM_ASSETS.getCode());
            List<AppAssetEntity> assetList = appAssetService.selectList(tAppAsset);
            if(assetList==null || assetList.size()==0) {
                AppUserEntity user = appUserService.getUserByUserId(loginUserId);
                appUserService.initAppUserAsset(user);
                return error(MessageUtils.message("c2c.order.availableAmount.buzu"));//您的可用资产不足
            }
            AppAssetEntity sellerAsset = assetList.get(0);
            if (sellerAsset.getAvailable().compareTo(symbolAmount) == -1) {
                return error(MessageUtils.message("c2c.order.availableAmount.insufficient"));//您的可用资产必须大于卖出数量
            }
        }

        BigDecimal adMinBuyNum = minAmount.divide(price,2,BigDecimal.ROUND_DOWN);
        if(availableNum.compareTo(adMinBuyNum)==-1) {
            c2cAdService.updateC2cAdDisabled(c2cAd);
            return error(MessageUtils.message("c2c.order.param.adid.invalid"));//广告已不可用
        }

//        if(c2cAdService.selectAdFromRedis(c2cOrder.getC2cAdId())==null) {
//            c2cAdService.setAdCache(c2cAd);
//        }
        //买入对应广告卖出
        if(direction.intValue() == c2cAd.getDirection().intValue()) {
            return error(MessageUtils.message("c2c.order.direction.invalid"));//参数direction值不正确
        }
        if(c2cAd.getUserId().longValue() == loginUserId) {
            return error(MessageUtils.message("c2c.order.buyer.seller.must.different"));//买家和卖家不能是同一个用户
        }

        if (legalCoinAmount.compareTo(minAmount) == -1) {
            return error(MessageUtils.message("c2c.order.param.tranAmt.min"));//金额必须大于广告最小限额
        }
        if (legalCoinAmount.compareTo(maxAmount) == 1) {
            return error(MessageUtils.message("c2c.order.param.tranAmt.max"));//金额必须小于广告最大限额
        }
        if(symbolAmount.compareTo(availableNum)==1) {
            return error(MessageUtils.message("c2c.order.param.tranAmt.over.avail"));//交易金额超过广告可用数量
        }

        //获取锁对象
        String lockKey = getC2cAdLockKey(c2cOrder.getC2cAdId().toString());
        if (distributedRedisLock.lock(lockKey)) {
            try {
                return c2cOrderService.createC2cOrder(c2cOrder, c2cAd, legalCoinAmount,symbolAmount, loginUserId, appUserDetail.getRealName());
            } catch (Exception e) {
                log.error("createC2cOrder,{},{},{}",loginUserId,c2cOrder.getC2cAdId(),e.getMessage());
                return error(e.getMessage());
            } finally {
                distributedRedisLock.unlock(lockKey);
            }
        }
        return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
    }

    @Operation(summary = "查询进行中的订单")
    @PostMapping("/myOrder")
    public Result myOrder()
    {
        String odUserKey = CacheConstants.getC2cOrderKeyByUid(StpUtil.getLoginIdAsString());
        String orderId = (String)redisUtils.get(odUserKey);
        if(StrUtil.isNotEmpty(orderId)) {
            C2cOrderEntity order = c2cOrderService.selectOrder(Long.valueOf(orderId));
            if(order==null) {
                return error("未找到进行中的交易");
            }
            //查卖家的收款信息
            Long sellUserId = null;
            if(order.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
                sellUserId = order.getTranUserId();
            } else {
                sellUserId = order.getUserId();
            }
            C2cUserReceiptEntity receipt = c2cUserReceiptService.selectOneMyReceipt(sellUserId,order.getPayType());
            order.setReceiptInfo(receipt);
            return success(order);
        }
        return error("未找到进行中的交易");

    }

    @Operation(summary = "用户取消订单")
    @PostMapping("/cancelOrder")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result cancelOrder(@RequestBody C2cOrderIdDTO dto)
    {
        ValidatorUtils.validateEntity(dto);

        C2cOrderEntity order = c2cOrderService.selectOrder(dto.getId());
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }

        if(order.getFlow().intValue() == C2cOrderFlowEnum.END.getCode().intValue()) {
            return error(MessageUtils.message("c2c.order.status.end.not.cancel"));//订单已结束不能取消
        }

        if(order.getStatus().intValue() == C2cOrderStatusEnum.COMPLAIN.getCode().intValue()) {
            return error(MessageUtils.message("c2c.order.complain.not.cancel"));//订单申诉中不能取消
        }

        //用户卖出对方已付款
        if(order.getDirection().intValue() == DirectionEnum.SELL.getCode().intValue()) {
            if(order.getStatus().intValue() == C2cOrderStatusEnum.PAY.getCode().intValue()) {
                return error(MessageUtils.message("c2c.order.sell.payed.not.cancel"));//卖出订单已付款不能取消
            }
        }

        String lockKey = getC2cOrderLockKey(order.getId().toString());
        if (distributedRedisLock.lock(lockKey)) {
            int oldStatus = order.getStatus().intValue();
            try {
                order.setRemark("用户主动取消订单");
                c2cOrderService.cancelC2cOrder(order, StpUtil.getLoginIdAsLong());
            } catch (Exception e) {
                log.error("cancelOrder,{},{}",order.getId(),e.getMessage());
                return error("取消订单失败");
            } finally {
                distributedRedisLock.unlock(lockKey);
            }
            c2cOrderService.cancelC2cOrderRedis(oldStatus, order);
            return success();
        }
        return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
    }


    @Operation(summary = "我已完成付款按钮")
    @PostMapping("/confirmPay")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result confirmPay(@RequestBody C2cOrderIdDTO dto)
    {
        ValidatorUtils.validateEntity(dto);

        C2cOrderEntity order = c2cOrderService.selectOrder(dto.getId());
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }

        long loginId = StpUtil.getLoginIdAsLong();
        Long buyUserId  = null;
        if(order.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
            buyUserId = order.getUserId();
        } else {
            buyUserId = order.getTranUserId();
        }
        if(buyUserId.longValue()!=loginId) {
            return error(MessageUtils.message("c2c.order.pay.not.buyer"));//您不是买家
        }

        if(order.getStatus().intValue() == C2cOrderStatusEnum.PAY.getCode()) {
            //前端重复调用，修改凭证，提交后提示成功
            return success();
        }

        if(order.getFlow().intValue() == C2cOrderFlowEnum.END.getCode()) {
            return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
        }

        String lockKey = getC2cOrderLockKey(order.getId().toString());
        if (distributedRedisLock.lock(lockKey)) {
            try {
                order.setRemark("买家已完成付款");
                return c2cOrderService.confirmPay(order, loginId);
            } catch (Exception e) {
                log.error("confirmPay,{},{}",order.getId(),e.getMessage());
                return error(e.getMessage());
            } finally {
                distributedRedisLock.unlock(lockKey);
            }
        }
        return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
    }


    @Operation(summary = "卖家确认收款按钮")
    @PostMapping("/verifyReceipt")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result verifyReceipt(@RequestBody C2cOrderIdDTO dto)
    {
        ValidatorUtils.validateEntity(dto);

        C2cOrderEntity order = c2cOrderService.selectOrder(dto.getId());
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }
        if(order.getFlow().intValue() == C2cOrderFlowEnum.END.getCode().intValue()) {
            return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
        }
        String lockKey = getC2cOrderLockKey(order.getId().toString());
        if (distributedRedisLock.lock(lockKey)) {
            try {
                order.setRemark("卖家已确认收款并放行");
                return toAjax(c2cOrderService.verifyReceipt(order,StpUtil.getLoginIdAsLong()));
            } catch (Exception e) {
                log.error("verifyReceipt,{},{}",order.getId(),e.getMessage());
                return error(e.getMessage());
            } finally {
                distributedRedisLock.unlock(lockKey);
            }
        }
        return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
    }


    @Operation(summary = "查订单付款凭证")
    @PostMapping("/queryPayment")
    public Result queryPayment(@RequestBody C2cPaymentVoucherQryDTO c2cPaymentVoucher)
    {
        ValidatorUtils.validateEntity(c2cPaymentVoucher);

        Long orderId = c2cPaymentVoucher.getOrderId();
        C2cOrderEntity order = c2cOrderService.selectOrder(orderId);
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }
        if(order.getUserId().longValue() == StpUtil.getLoginIdAsLong()
                || order.getTranUserId().longValue() == StpUtil.getLoginIdAsLong()) {
            List<C2cPaymentVoucherEntity> list = c2cPaymentVoucherService.selectList(orderId);
            return success(list);
        } else {
            return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
        }
    }


    @Operation(summary = "上传付款凭证")
    @PostMapping("/uploadPayment")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result uploadPayment(@RequestBody C2cPaymentVoucherDTO c2cPaymentVoucher) {
        ValidatorUtils.validateEntity(c2cPaymentVoucher);

        Long orderId = c2cPaymentVoucher.getOrderId();
        String img = c2cPaymentVoucher.getImg();

        C2cOrderEntity order = c2cOrderService.selectOrder(orderId);
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }
        if(order!=null && order.getFlow().intValue()==C2cOrderFlowEnum.END.getCode()) {
            return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
        }

        if(order.getUserId().longValue() != StpUtil.getLoginIdAsLong()
                && order.getTranUserId().longValue() != StpUtil.getLoginIdAsLong()) {
            return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
        }


        if(c2cPaymentVoucher.getId() == null || c2cPaymentVoucher.getId().intValue() == 0) {
            C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
            entity.setOrderId(orderId);
            entity.setUserId(StpUtil.getLoginIdAsLong());
            entity.setImg(img);
            entity.setStatus(1);
            entity.setCreateTime(new Date());
            entity.setUpdateTime(new Date());
            if(c2cPaymentVoucherService.insert(entity)) {
                Map data = MapUtil.of("id", entity.getId());
                return success(data);
            } else {
                return error(MessageUtils.message("c2c.order.uploadPayment.fail"));//上传付款凭证失败
            }

        } else {
            C2cPaymentVoucherEntity voucher = c2cPaymentVoucherService.selectById(c2cPaymentVoucher.getId());
            if(voucher==null) {
                return error(MessageUtils.message("c2c.order.pay.cert.id.invalid"));//凭证编号无效
            }
            if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {

                C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
                entity.setId(c2cPaymentVoucher.getId());
                entity.setOrderId(orderId);
                entity.setUserId(StpUtil.getLoginIdAsLong());
                entity.setImg(img);
                entity.setStatus(1);
                entity.setUpdateTime(new Date());
                if(c2cPaymentVoucherService.updateById(entity)) {
                    Map data = MapUtil.of("id", entity.getId());
                    return success(data);
                } else {
                    return error(MessageUtils.message("c2c.order.uploadPayment.fail"));//上传付款凭证失败
                }

            } else {
                return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
            }
        }
    }


    @Operation(summary = "删除付款凭证")
    @PostMapping("/deletePayment")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result deletePayment(@RequestBody C2cPaymentVoucherIdDTO c2cPaymentVoucher) {
        ValidatorUtils.validateEntity(c2cPaymentVoucher);

        C2cPaymentVoucherEntity voucher = c2cPaymentVoucherService.selectById(c2cPaymentVoucher.getId());
        if(voucher==null) {
            return error(MessageUtils.message("c2c.order.pay.cert.id.invalid"));//凭证编号无效
        }
        //订单已完成不能删除
        C2cOrderEntity order = c2cOrderService.selectOrder(voucher.getOrderId());
        if(order!=null && order.getFlow().intValue()==C2cOrderFlowEnum.END.getCode()) {
            return error(MessageUtils.message("c2c.order.is.end"));//订单已结束
        }

        if(StpUtil.getLoginIdAsString().equals(voucher.getUserId().toString())) {

            C2cPaymentVoucherEntity entity = new C2cPaymentVoucherEntity();
            entity.setId(c2cPaymentVoucher.getId());
            entity.setStatus(-1);
            entity.setUpdateTime(new Date());
            return toAjax(c2cPaymentVoucherService.updateById(entity));
        } else {
            return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
        }
    }

    @Operation(summary = "用户或商家查询订单历史")
    @PostMapping("/mylist")
    public Result mylist(@RequestBody C2cOrderListDTO orderVo)
    {
        ValidatorUtils.validateEntity(orderVo);
        //分页
        String pageNum = Convert.toStr(orderVo.getPageNum(),"1");
        String pageSize = Convert.toStr(orderVo.getPageSize(),"10");

        Map<String,Object> params = new HashMap<>();
        params.put(Constant.PAGE,pageNum);
        params.put(Constant.LIMIT,pageSize);
        params.put("direction",orderVo.getDirection());
        params.put("flow",orderVo.getFlow());
        params.put("status",orderVo.getStatus());
        params.put("orderNo",orderVo.getOrderNo());
        params.put("isMt",orderVo.getIsMt());
        PageData<C2cOrderEntity> page = c2cOrderService.page(params);

        List<C2cOrderEntity> orderList = page.getList();
        // 查询付款凭证
        orderList = c2cOrderService.selectPaymentVoucherByOrderList(orderList);
        page.setList(orderList);


        return new Result<PageData<C2cOrderEntity>>().ok(page);

    }

    @Operation(summary = "c2c订单详细信息")
    @GetMapping(value = "/{id}")
    public Result getInfo(@PathVariable("id") Long id)
    {
        C2cOrderEntity c2cOrder = c2cOrderService.selectOrder(id);
        if(c2cOrder == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }
        if(c2cOrder.getUserId().longValue() != StpUtil.getLoginIdAsLong()
                && c2cOrder.getTranUserId().longValue() != StpUtil.getLoginIdAsLong()) {
            return error(MessageUtils.message("c2c.order.no.permission.view"));//您无权查看
        }

        //买家付款凭证
        C2cPaymentVoucherEntity c2cPaymentVoucher = new C2cPaymentVoucherEntity();
        c2cPaymentVoucher.setOrderId(c2cOrder.getId());
        c2cPaymentVoucher.setStatus(1);
        List<C2cPaymentVoucherEntity> payVoucherList = c2cPaymentVoucherService.selectList(c2cOrder.getId());
        if(payVoucherList!=null && payVoucherList.size()>0) {
            c2cOrder.setIsVoucher(1);
            c2cOrder.setPayVoucherList(payVoucherList);
        } else {
            c2cOrder.setIsVoucher(0);
        }
        //卖家收款信息
        Long sellUserId = null;
        if(c2cOrder.getDirection().intValue() == DirectionEnum.BUY.getCode().intValue()) {
            sellUserId = c2cOrder.getTranUserId();
        } else {
            sellUserId = c2cOrder.getUserId();
        }
        C2cUserReceiptEntity receipt = c2cUserReceiptService.selectOneMyReceipt(sellUserId, c2cOrder.getPayType());
        c2cOrder.setReceiptInfo(receipt);

        return success(c2cOrder);

    }


    @Operation(summary = "商户统计待处理数")
    @PostMapping("/undoCounts")
    public Result undoCounts() {
        //待支付的订单数量
        String unpayCountsKey = CacheConstants.getC2cMertUnPayKey(StpUtil.getLoginIdAsString());

        //待放币的订单数量
        String releaseCountsKey = CacheConstants.getC2cMertUnReleaseKey(StpUtil.getLoginIdAsString());

        Integer unpayCounts = 0;
        Integer releaseCounts = 0;
        if(!redisUtils.hasKey(unpayCountsKey)) {
            unpayCounts = c2cOrderService.setMtUnPayCount(unpayCountsKey);
        } else {
            unpayCounts = Convert.toInt(redisUtils.get(unpayCountsKey),0);
        }
        if(!redisUtils.hasKey(releaseCountsKey)) {
            releaseCounts = c2cOrderService.setMtUnReleaseCount(releaseCountsKey);
        } else {
            releaseCounts = Convert.toInt(redisUtils.get(releaseCountsKey),0);
        }

        if(unpayCounts<0 || releaseCounts<0) {
            unpayCounts = c2cOrderService.setMtUnPayCount(unpayCountsKey);
            releaseCounts = c2cOrderService.setMtUnReleaseCount(releaseCountsKey);
        }
        Map<String,Integer> data = MapUtil.of("unpayCounts",unpayCounts);
        data.put("releaseCounts",releaseCounts);
        return success(data);
    }

    @Operation(summary = "用户/商家发起申诉")
    @PostMapping("/complain")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result complain(@RequestBody C2cOrderComplainDTO c2cOrderComplain)
    {
        ValidatorUtils.validateEntity(c2cOrderComplain);

        C2cOrderEntity order = c2cOrderService.selectOrder(c2cOrderComplain.getOrderId());
        log.info("订单信息："+ JSON.toJSONString(order));
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }

        //只有已付款才能发起申诉
        if(order.getStatus().intValue() != C2cOrderStatusEnum.PAY.getCode().intValue()) {
            //当前订单状态({0})不能发起申诉
            return error(MessageUtils.message("c2c.order.status.complain.fail",C2cOrderStatusEnum.getByKey(order.getStatus().intValue()).getDesc()));
        }

        if(order.getUserId().longValue() != StpUtil.getLoginIdAsLong()
                && order.getTranUserId().longValue() != StpUtil.getLoginIdAsLong()) {
            return error(MessageUtils.message("c2c.complain.submit.fail"));//发起申诉失败，您不是买家或卖家
        }

        if(c2cOrderComplain.getReason().length()>250) {
            return error(MessageUtils.message("c2c.order.complain.remark.maxval"));//申诉原因最多250个字
        }

        try {
            C2cOrderComplainEntity c2cOrderComplainEntity = new C2cOrderComplainEntity();
            c2cOrderComplainEntity.setOrderId(c2cOrderComplain.getOrderId());
            c2cOrderComplainEntity.setReason(c2cOrderComplain.getReason());
            return c2cOrderService.complain(order,c2cOrderComplainEntity,StpUtil.getLoginIdAsLong());
        } catch (Exception e) {
            return error(e.getMessage());
        }

    }


    @Operation(summary = "用户或商家提交申诉凭证")
    @PostMapping("/complainVoucher")
    @RepeatSubmit(interval = 3000, message = "请求过于频繁")
    public Result complainVoucher(@RequestBody C2cOrderComplainVoucherDTO dto)
    {
        ValidatorUtils.validateEntity(dto);

        C2cOrderComplainEntity orderComplain = orderComplainService.selectById(dto.getComplainId());
        if(orderComplain == null) {
            return error(MessageUtils.message("c2c.order.complain.not.exist"));//申诉编号无效
        }

        if( StpUtil.getLoginIdAsLong() != orderComplain.getFromUserId().longValue()
                && StpUtil.getLoginIdAsLong() != orderComplain.getToUserId().longValue()) {
            return error(MessageUtils.message("c2c.complain.voucher.submit.fail"));//提交失败，您不是申诉人或被申诉人
        }

        if(StrUtil.isEmpty(dto.getRemark())) {
            return error(MessageUtils.message("c2c.order.complain.remark.notEmpty"));//申诉原因不能空
        }
        if(dto.getRemark().length()>250) {
            return error(MessageUtils.message("c2c.order.complain.remark.maxval"));//描述最多250个字
        }

        if(dto.getId()==null || dto.getId().intValue()==0) {
            C2cOrderComplainVoucherEntity voucherEntity = new C2cOrderComplainVoucherEntity();
            voucherEntity.setComplainId(dto.getComplainId());
            voucherEntity.setRemark(dto.getRemark());
            voucherEntity.setImg1(dto.getImg1());
            voucherEntity.setImg2(dto.getImg2());
            voucherEntity.setImg3(dto.getImg3());
            voucherEntity.setImg4(dto.getImg4());
            voucherEntity.setImg5(dto.getImg5());
            voucherEntity.setUserId(StpUtil.getLoginIdAsLong());
            voucherEntity.setStatus(1);
            voucherEntity.setCreateTime(new Date());
            voucherEntity.setUpdateTime(new Date());
            if(orderComplainVoucherService.insert(voucherEntity)) {
                Map data = MapUtil.of("id", voucherEntity.getId());
                return success(data);
            } else {
                return error(MessageUtils.message("c2c.order.complain.voucher.save.fail"));//保存申诉凭证失败
            }

        } else {
            C2cOrderComplainVoucherEntity voucherEntity = orderComplainVoucherService.selectById(dto.getId());
            if(voucherEntity==null) {
                return error(MessageUtils.message("c2c.order.complain.voucher.id.invalid"));//申诉凭证编号无效
            }
            if(orderComplain.getFlow().intValue() == C2cOrderFlowEnum.END.getCode()) {
                return error(MessageUtils.message("c2c.order.complain.voucher.is.end"));//申诉已结束
            }
            if(StpUtil.getLoginIdAsLong() == voucherEntity.getUserId().longValue()) {
                voucherEntity.setComplainId(dto.getComplainId());
                voucherEntity.setRemark(dto.getRemark());
                voucherEntity.setImg1(dto.getImg1());
                voucherEntity.setImg2(dto.getImg2());
                voucherEntity.setImg3(dto.getImg3());
                voucherEntity.setImg4(dto.getImg4());
                voucherEntity.setImg5(dto.getImg5());
                voucherEntity.setUserId(StpUtil.getLoginIdAsLong());
                voucherEntity.setStatus(1);
                voucherEntity.setUpdateTime(new Date());
                if(orderComplainVoucherService.updateById(voucherEntity)) {
                    Map data = MapUtil.of("id", voucherEntity.getId());
                    return success(data);
                } else {
                    return error(MessageUtils.message("c2c.order.complain.voucher.update.fail"));//修改申诉凭证失败
                }
            } else {
                return error(MessageUtils.message("operation.fail.please.refresh"));//操作失败，请刷新后重试
            }

        }


    }

    @Operation(summary = "用户或商家查询申诉历史")
    @PostMapping("/complainHis")
    public Result complainHis(@RequestBody C2cOrderComplainOidDTO orderComplain)
    {
        ValidatorUtils.validateEntity(orderComplain);

        List<C2cOrderComplainEntity> complainList = new ArrayList<>();
        C2cOrderEntity order = c2cOrderService.selectOrder(orderComplain.getOrderId());
        if(order == null) {
            return error(MessageUtils.message("c2c.order.not.exist"));//订单编号无效
        }

        if( StpUtil.getLoginIdAsLong() != order.getUserId().longValue()
                && StpUtil.getLoginIdAsLong() != order.getTranUserId().longValue()) {
            return error(MessageUtils.message("c2c.order.no.permission.view"));//您无权查看
        }

        if(c2cOrderService.checkOrderTranUser(order)) {
            complainList = orderComplainService.selectC2cOrderComplainList(orderComplain.getOrderId());
        }
        return success(complainList);
    }

    @Operation(summary = "用户或商家申诉详情")
    @PostMapping("/complainDetail")
    public Result complainDetail(@RequestBody C2cOrderComplainDetailDTO dto)
    {
        ValidatorUtils.validateEntity(dto);
        if(dto.getOrderId() == null && dto.getComplainId() == null) {
            return error(MessageUtils.message("c2c.order.complainId.orderId.all.empty"));//申诉编号、订单编号不能都为空
        }

        C2cOrderComplainEntity orderComplain = null;
        if (dto.getComplainId() != null) {
            orderComplain = orderComplainService.selectById(dto.getComplainId());
        } else {
            List<C2cOrderComplainEntity> orderComplainList = orderComplainService.selectC2cOrderComplainList(dto.getOrderId());
            orderComplain = orderComplainList.get(0);
        }

        if(orderComplain==null) {
            return error(MessageUtils.message("c2c.order.complainId.orderId.invalid"));//申诉编号或订单编号无效
        }

        if(StpUtil.getLoginIdAsLong() != orderComplain.getFromUserId().longValue()
                && StpUtil.getLoginIdAsLong() != orderComplain.getToUserId().longValue()) {
            return error(MessageUtils.message("c2c.order.no.permission.view"));//您无权查看
        }

        List<C2cOrderComplainVoucherEntity> complainList = new ArrayList<>();
        C2cOrderEntity order = c2cOrderService.selectOrder(orderComplain.getOrderId());

        if(c2cOrderService.checkOrderTranUser(order)) {
            complainList = orderComplainVoucherService.selectList(orderComplain.getId());
        }
        Map data = MapUtil.of("complainInfo", orderComplain);
        data.put("voucherList", complainList);
        return success(data);
    }


    /**
     * c2c我的信息
     *
     */
    @Operation(summary = "c2c我的")
    @PostMapping("/myInfo")
    public Result myInfo()
    {
        AppUserEntity user = appUserService.selectById(StpUtil.getLoginIdAsLong());
        AppUserDetailEntity detail = appUserDetailService.selectAppUserDetailByUserId(user.getId());
        AppAssetEntity asset = appAssetService.getAppAssetEntity(user.getId(), "usdt",AssetEnum.PLATFORM_ASSETS.getCode());
        C2cMerchantEntity merchant = c2cMerchantService.getMerchantEntity(user.getId());

        Map data = MapUtil.of("email", user.getEmail());
        data.put("loginName",user.getLoginName());
        data.put("country", user.getCountry());
        data.put("phone", user.getPhone());
        data.put("register_time", DateUtils.format(user.getCreateTime(),"yyyy/MM/dd"));
        data.put("auth_time", DateUtils.format(detail.getOperateTime(),"yyyy/MM/dd"));
        data.put("avail",asset.getAvailable().setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
        data.put("frozen",asset.getFrozen().setScale(8, RoundingMode.DOWN).stripTrailingZeros().toPlainString());
        data.put("finishNum",merchant.getFinishNum());
        data.put("finishRate",merchant.getFinishRate());
        data.put("averagePayTime",merchant.getAveragePayTime());
        data.put("averagePassTime",merchant.getAveragePassTime());

        return success(data);
    }


}
