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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import shop.alien.entity.store.MerchantPaymentOrder;
import shop.alien.mapper.MerchantPaymentOrderMapper;
import shop.alien.store.service.MerchantPaymentOrderService;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

/**
 * 商户支付单表 服务实现类
 *
 * @author system
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class MerchantPaymentOrderServiceImpl extends ServiceImpl<MerchantPaymentOrderMapper, MerchantPaymentOrder> implements MerchantPaymentOrderService {

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

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

    @Override
    public int logicDeleteByOrderId(Integer orderId) {
        if (orderId == null) {
            return 0;
        }
        LambdaUpdateWrapper<MerchantPaymentOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MerchantPaymentOrder::getOrderId, orderId);
        wrapper.set(MerchantPaymentOrder::getDeleteFlag, 1);
        return baseMapper.update(null, wrapper);
    }

    @Override
    public int logicDeleteByOrderIdAndPayType(Integer orderId, String payType) {
        if (orderId == null || payType == null || payType.trim().isEmpty()) {
            return 0;
        }
        LambdaUpdateWrapper<MerchantPaymentOrder> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(MerchantPaymentOrder::getOrderId, orderId);
        wrapper.eq(MerchantPaymentOrder::getPayType, payType.trim());
        wrapper.set(MerchantPaymentOrder::getDeleteFlag, 1);
        return baseMapper.update(null, wrapper);
    }

    @Override
    public MerchantPaymentOrder getPaidByOrderId(Integer orderId) {
        if (orderId == null) {
            return null;
        }
        LambdaQueryWrapper<MerchantPaymentOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MerchantPaymentOrder::getOrderId, orderId);
        wrapper.eq(MerchantPaymentOrder::getPayStatus, 1);
        wrapper.eq(MerchantPaymentOrder::getOrderType, "reservation_order");
        wrapper.last("LIMIT 1");
        return this.getOne(wrapper);
    }

    @Override
    public MerchantPaymentOrder getUnpaidByOrderId(Integer orderId) {
        if (orderId == null) {
            return null;
        }
        LambdaQueryWrapper<MerchantPaymentOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MerchantPaymentOrder::getOrderId, orderId);
        wrapper.eq(MerchantPaymentOrder::getPayStatus, 0);
        wrapper.eq(MerchantPaymentOrder::getOrderType, "reservation_order");
        wrapper.last("LIMIT 1");
        return this.getOne(wrapper);
    }

    @Override
    public List<MerchantPaymentOrder> listUnpaidRecent(int withinMinutes) {
        if (withinMinutes <= 0) {
            return Collections.emptyList();
        }
        Calendar cal = Calendar.getInstance();
        cal.add(Calendar.MINUTE, -withinMinutes);
        Date since = cal.getTime();
        LambdaQueryWrapper<MerchantPaymentOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(MerchantPaymentOrder::getPayStatus, 0);
        wrapper.eq(MerchantPaymentOrder::getOrderType, "reservation_order");
        wrapper.ge(MerchantPaymentOrder::getCreatedTime, since);
        wrapper.orderByAsc(MerchantPaymentOrder::getCreatedTime);
        return this.list(wrapper);
    }
}
