package com.clx.performance.service.impl.breakcontract;

import com.clx.performance.constant.RedissonConstants;
import com.clx.performance.dao.breakcontract.BreakContractSettlementDriverDao;
import com.clx.performance.enums.BreakContractSettlementDriverEnum;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.model.breakcontract.BreakContractSettlementDriver;
import com.clx.performance.service.breakcontract.BreakContractJobHandlerService;
import com.clx.performance.service.payment.PayService;
import com.msl.common.exception.ServiceSystemException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Slf4j
@Service
public class BreakContractJobHandlerServiceImpl implements BreakContractJobHandlerService {

    @Autowired
    private BreakContractSettlementDriverDao breakContractSettlementDriverDao;

    @Autowired
    private PayService payService;

    @Autowired
    private RedissonClient redissonClient;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String pay(Integer settlementId){
        RLock lock = redissonClient.getLock(RedissonConstants.BREAK_CONTRACT_SETTLEMENT_OWNER_BATCH_PAY_ID_LOCK + settlementId);
        try{
            boolean flag = lock.tryLock(15, 30, TimeUnit.SECONDS);
            if (!flag) {
                //说明有别的线程发起支付操作
                return "车主违约结算单支付,支付操作频繁，稍后重试";
            }
            String msg = null;
            BreakContractSettlementDriver breakContractSettlementDriver = breakContractSettlementDriverDao.getEntityByKey(settlementId).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

            if (Objects.equals(breakContractSettlementDriver.getSettleStatus(), BreakContractSettlementDriverEnum.SettleStatus.YES)){
                return msg;
            }

            try {
                pay(breakContractSettlementDriver);
            }catch (ServiceSystemException e){
                breakContractSettlementDriver.setPayRemark(e.getMessage());
                breakContractSettlementDriverDao.updatePayFail(breakContractSettlementDriver);
                msg = e.getMessage();
            }
            return msg;
        }catch(Exception e){
            log.warn("结算单批量支付上锁失败，结算单ID：{},异常原因:{}", settlementId,ExceptionUtils.getStackTrace(e));
            throw new ServiceSystemException(PerformanceResultEnum.TRY_LOCK_ERROR);
        }finally {
            if (lock.isLocked() && lock.isHeldByCurrentThread()) {
                lock.unlock();
            }
        }
    }

    /**
     * 支付
     */
    private void pay(BreakContractSettlementDriver settlement){

        // 车主
        if (Objects.equals(settlement.getBreakContractPartyType(), BreakContractSettlementDriverEnum.BreakContractPartyType.DRIVER.getCode())){

            payService.driverPay(settlement.getSettlementNo(), settlement.getTruckOwnUserNo(), settlement.getFigure().intValue());
        }
        // 平台
        else if (Objects.equals(settlement.getBreakContractPartyType(), BreakContractSettlementDriverEnum.BreakContractPartyType.PLATFORM.getCode())) {
            payService.payDriver(settlement.getSettlementNo(), settlement.getTruckOwnUserNo(), settlement.getFigure().intValue());

        }
    }

}
