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

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.component.OrderChildLoanComponent;
import com.clx.performance.constant.RabbitKeyConstants;
import com.clx.performance.dao.OrderChildDao;
import com.clx.performance.dao.loan.OrderChildLoanRetryRecordDao;
import com.clx.performance.dao.loan.OwnerLoanAccountDao;
import com.clx.performance.dao.settle.SettlementDriverDetailDao;
import com.clx.performance.dao.settle.SettlementOwnerDetailDao;
import com.clx.performance.dto.OwnerLoanMqDTO;
import com.clx.performance.model.OrderChild;
import com.clx.performance.model.breakcontract.BreakContractSettlementDriver;
import com.clx.performance.model.loan.OrderChildLoanRetryRecord;
import com.clx.performance.model.loan.OwnerLoanAccount;
import com.clx.performance.model.settle.SettlementDriverDetail;
import com.clx.performance.model.settle.SettlementOwnerDetail;
import com.clx.performance.param.pc.loan.carrier.PageOwnerLoanAccountParam;
import com.clx.performance.service.loan.OwnerLoanAccountService;
import com.clx.performance.struct.loan.OwnerLoanAccountStruct;
import com.clx.performance.vo.pc.loan.carrier.CarrierOwnerLoanAccountVO;
import com.clx.performance.vo.pc.loan.owner.OwnerAccountVO;
import com.msl.common.base.Optional;
import com.msl.common.convertor.aspect.UnitCovert;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageBuilder;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author kavin
 * Date 2024-01-20
 * Time 13:31
 */
@Service
@Slf4j
@AllArgsConstructor
public class OwnerLoanAccountServiceImpl implements OwnerLoanAccountService {

    private final OwnerLoanAccountDao ownerLoanAccountDao;

    private final OwnerLoanAccountStruct ownerLoanAccountStruct;

    private final OrderChildDao orderChildDao;

    private final SettlementDriverDetailDao settlementDriverDetailDao;

    private final SettlementOwnerDetailDao settlementOwnerDetailDao;

    private final OrderChildLoanRetryRecordDao orderChildLoanRetryRecordDao;

    private final RabbitTemplate rabbitTemplate;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void openOwnerLoanAccount(Long ownerUserNo, String ownerUserName, String mobile) {
        OwnerLoanAccount entity = new OwnerLoanAccount();
        entity.setOwnerUserNo(ownerUserNo);
        entity.setMobile(mobile);
        entity.setOwnerUserName(ownerUserName);
        entity.setFundingAccountBalance(BigDecimal.ZERO);
        entity.setFundingFrozenBalance(BigDecimal.ZERO);
        entity.setFundingUsableBalance(BigDecimal.ZERO);
        entity.setFundingArrears(BigDecimal.ZERO);

        entity.setVirtuallyArrears(BigDecimal.ZERO);
        entity.setVirtuallyAccountBalance(BigDecimal.ZERO);
        entity.setVirtuallyUsableBalance(BigDecimal.ZERO);
        entity.setVirtuallyFrozenBalance(BigDecimal.ZERO);
        ownerLoanAccountDao.saveEntity(entity);
    }

    @Override
    @UnitCovert(param = false)
    public IPage<CarrierOwnerLoanAccountVO> pageOwnerLoanAccount(PageOwnerLoanAccountParam param) {
        return ownerLoanAccountDao.pageByParam(param);
    }

    @Override
    public OwnerAccountVO getOwnerLoanAccount() {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();
        Optional<OwnerLoanAccount> optional = ownerLoanAccountDao.getOneByField(OwnerLoanAccount::getOwnerUserNo,
                loginUserInfo.getUserNo());
        if (!optional.isPresent()) {
            return OwnerAccountVO.builder().openAccount(0).build();
        }
        OwnerLoanAccount ownerLoanAccount = optional.get();
        OwnerAccountVO ownerAccountVO = ownerLoanAccountStruct.convertVO(ownerLoanAccount);
        ownerAccountVO.setOpenAccount(1);
        return ownerAccountVO;
    }

    /**
     * 货主借款后执行阻塞流程的相关运单
     *
     * @param ownerUserNo
     */
    @Override
    public void orderChildLoanProcess(Long ownerUserNo) {
        List<OrderChildLoanRetryRecord> orderChildLoanRetryRecordList = orderChildLoanRetryRecordDao.selectListByIdAsc();
        for (OrderChildLoanRetryRecord retryRecord : orderChildLoanRetryRecordList) {
            //生成借款标识
            SettlementDriverDetail settlementDriverDetail = settlementDriverDetailDao.getEntityByKey(retryRecord.getSettlementDriverId()).get();
            SettlementOwnerDetail settlementOwnerDetail = settlementOwnerDetailDao.getEntityByKey(retryRecord.getSettlementOwnerId()).get();
            OrderChild orderChild = orderChildDao.getByChildNo(settlementDriverDetail.getChildNo()).get();
            OwnerLoanMqDTO dto = new OwnerLoanMqDTO();
            dto.setSettlementOwnerDetail(settlementOwnerDetail);
            dto.setSettlementDriverDetail(settlementDriverDetail);
            dto.setOrderChild(orderChild);
            //货主借款监听器处理
            Message message = MessageBuilder.withBody(JSONUtil.parse(dto).toString().getBytes()).build();
            rabbitTemplate.send(
                    RabbitKeyConstants.OWNER_LOAN_EXCHANGE, RabbitKeyConstants.OWNER_LOAN_ROUTE_KEY, message
            );
            orderChildLoanRetryRecordDao.deleteByKey(retryRecord.getId());
        }
    }

}

