package shop.alien.store.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.PlatformShopMembershipOrder;
import shop.alien.entity.store.PlatformShopMembershipPaymentOrder;
import shop.alien.mapper.PlatformShopMembershipOrderMapper;
import shop.alien.mapper.PlatformShopMembershipPaymentOrderMapper;
import shop.alien.store.service.PlatformShopMembershipOrderService;
import shop.alien.store.service.PlatformShopMembershipPaymentOrderService;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.ThreadLocalRandom;

@Service
@Transactional(rollbackFor = Exception.class)
public class PlatformShopMembershipPaymentOrderServiceImpl
        extends ServiceImpl<PlatformShopMembershipPaymentOrderMapper, PlatformShopMembershipPaymentOrder>
        implements PlatformShopMembershipPaymentOrderService {

    @Resource
    private PlatformShopMembershipOrderMapper membershipOrderMapper;

    @Resource
    private PlatformShopMembershipOrderService platformShopMembershipOrderService;

    @Override
    public PlatformShopMembershipPaymentOrder getByOutTradeNo(String outTradeNo) {
        if (outTradeNo == null || outTradeNo.trim().isEmpty()) {
            return null;
        }
        LambdaQueryWrapper<PlatformShopMembershipPaymentOrder> w = new LambdaQueryWrapper<>();
        w.eq(PlatformShopMembershipPaymentOrder::getOutTradeNo, outTradeNo.trim());
        return getOne(w);
    }

    @Override
    public String generatePaymentNo() {
        String dateStr = new SimpleDateFormat("yyyyMMddHHmmss").format(new Date());
        int random = ThreadLocalRandom.current().nextInt(10000);
        return "PMP" + dateStr + String.format("%04d", random);
    }

    @Override
    public int logicDeletePendingByMembershipOrderIdAndPayType(Integer membershipOrderId, String payType) {
        if (membershipOrderId == null || payType == null || payType.trim().isEmpty()) {
            return 0;
        }
        LambdaUpdateWrapper<PlatformShopMembershipPaymentOrder> u = new LambdaUpdateWrapper<>();
        u.eq(PlatformShopMembershipPaymentOrder::getMembershipOrderId, membershipOrderId);
        u.eq(PlatformShopMembershipPaymentOrder::getPayType, payType.trim());
        u.eq(PlatformShopMembershipPaymentOrder::getPayStatus, 0);
        u.set(PlatformShopMembershipPaymentOrder::getDeleteFlag, 1);
        u.set(PlatformShopMembershipPaymentOrder::getUpdatedTime, new Date());
        return baseMapper.update(null, u);
    }

    @Override
    public PlatformShopMembershipPaymentOrder findPaidPaymentForMembershipTestRefund(
            Integer membershipOrderId, String payType, String outTradeNo) {
        if (membershipOrderId == null || StringUtils.isBlank(payType)) {
            return null;
        }
        PlatformShopMembershipOrder ord = membershipOrderMapper.selectById(membershipOrderId);
        if (ord == null || ord.getStoreId() == null) {
            return null;
        }
        Integer storeId = ord.getStoreId();
        String pt = payType.trim();
        if (StringUtils.isNotBlank(outTradeNo)) {
            PlatformShopMembershipPaymentOrder po = getByOutTradeNo(outTradeNo.trim());
            if (po == null) {
                return null;
            }
            if (!membershipOrderId.equals(po.getMembershipOrderId())
                    || !storeId.equals(po.getStoreId())
                    || !pt.equals(po.getPayType())) {
                return null;
            }
            if (po.getPayStatus() == null || po.getPayStatus() != 1) {
                return null;
            }
            return po;
        }
        LambdaQueryWrapper<PlatformShopMembershipPaymentOrder> w = new LambdaQueryWrapper<>();
        w.eq(PlatformShopMembershipPaymentOrder::getMembershipOrderId, membershipOrderId);
        w.eq(PlatformShopMembershipPaymentOrder::getStoreId, storeId);
        w.eq(PlatformShopMembershipPaymentOrder::getPayType, pt);
        w.eq(PlatformShopMembershipPaymentOrder::getPayStatus, 1);
        w.orderByDesc(PlatformShopMembershipPaymentOrder::getPayTime).orderByDesc(PlatformShopMembershipPaymentOrder::getId);
        w.last("LIMIT 1");
        return getBaseMapper().selectOne(w);
    }

    @Override
    public void markPaymentAndMembershipOrderRefunded(PlatformShopMembershipPaymentOrder paymentOrder) {
        if (paymentOrder == null || paymentOrder.getId() == null) {
            return;
        }
        Date now = new Date();
        LambdaUpdateWrapper<PlatformShopMembershipPaymentOrder> uw = new LambdaUpdateWrapper<>();
        uw.eq(PlatformShopMembershipPaymentOrder::getId, paymentOrder.getId());
        uw.set(PlatformShopMembershipPaymentOrder::getPayStatus, PlatformShopMembershipPaymentOrder.PAY_STATUS_REFUNDED);
        uw.set(PlatformShopMembershipPaymentOrder::getUpdatedTime, now);
        update(uw);

        if (paymentOrder.getMembershipOrderId() != null) {
            LambdaUpdateWrapper<PlatformShopMembershipOrder> ow = new LambdaUpdateWrapper<>();
            ow.eq(PlatformShopMembershipOrder::getId, paymentOrder.getMembershipOrderId());
            ow.set(PlatformShopMembershipOrder::getPayStatus, PlatformShopMembershipOrder.PAY_STATUS_REFUNDED);
            ow.set(PlatformShopMembershipOrder::getUpdatedTime, now);
            platformShopMembershipOrderService.update(ow);
        }
    }
}
