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

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.clx.performance.dao.loan.BorrowerConfigDao;
import com.clx.performance.dao.loan.BorrowerDao;
import com.clx.performance.enums.PerformanceResultEnum;
import com.clx.performance.enums.loan.BorrowerEnum;
import com.clx.performance.model.loan.Borrower;
import com.clx.performance.param.pc.loan.carrier.*;
import com.clx.performance.service.loan.BorrowerService;
import com.clx.performance.struct.borrower.BorrowerStruct;
import com.clx.performance.vo.pc.loan.carrier.BorrowerVO;
import com.msl.common.base.Optional;
import com.msl.common.exception.ServiceSystemException;
import com.msl.user.data.UserSessionData;
import com.msl.user.utils.TokenUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Objects;

/**
 * @Author: aiqinguo
 * @Description: 借出方
 * @Date: 2024/01/17 13:42:57
 * @Version: 1.0
 */
@Slf4j
@Service
public class BorrowerServiceImpl implements BorrowerService {

    @Autowired
    private BorrowerDao borrowerDao;

    @Autowired
    private BorrowerConfigDao borrowerConfigDao;

    @Autowired
    private BorrowerStruct borrowerStruct;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBorrower(BorrowerAddParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        // 重复验证
        Optional<Borrower> borrowerOptional = borrowerDao.selectByName(param.getName());
        if (borrowerOptional.isPresent()) {
            throw new ServiceSystemException(PerformanceResultEnum.BORROWER_NAME_EXIST);
        }

        Borrower borrower = new Borrower();
        borrower.setName(param.getName());
        borrower.setBankName(param.getBankName());
        borrower.setBankCardNo(param.getBankCardNo());
        borrower.setOpenBankId(param.getOpenBankId());
        borrower.setOpenBankName(param.getOpenBankName());

        borrower.setOpUserNo(loginUserInfo.getUserNo());
        borrower.setOpUserName(loginUserInfo.getUserName());
        borrower.setOpTime(LocalDateTime.now());
        borrower.setCreateBy(loginUserInfo.getUserNo());
        borrower.setCreateName(loginUserInfo.getUserName());
        borrowerDao.saveEntity(borrower);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateBorrower(BorrowerUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        Borrower borrower = borrowerDao.getEntityByKey(param.getId()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        Optional<Borrower> borrowerOptional = borrowerDao.selectByName(param.getName());
        if (borrowerOptional.isPresent() && !Objects.equals(borrower.getId(), borrowerOptional.get().getId())) {
            throw new ServiceSystemException(PerformanceResultEnum.BORROWER_NAME_EXIST);
        }

        boolean updateNameFlag = !borrower.getName().equals(param.getName());

        borrower.setName(param.getName());
        borrower.setBankName(param.getBankName());
        borrower.setBankCardNo(param.getBankCardNo());
        borrower.setOpenBankId(param.getOpenBankId());
        borrower.setOpenBankName(param.getOpenBankName());

        borrower.setOpUserNo(loginUserInfo.getUserNo());
        borrower.setOpUserName(loginUserInfo.getUserName());
        borrower.setOpTime(LocalDateTime.now());

        borrowerDao.update(borrower);

        // 更新名称
        if (updateNameFlag) {
            borrowerConfigDao.updateName(borrower.getId(), borrower.getName());
        }
    }

    @Override
    public void updateStatus(BorrowerStatusUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        Borrower borrower = borrowerDao.getEntityByKey(param.getId()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);

        borrower.setStatus(param.getStatus());
        borrower.setOpUserNo(loginUserInfo.getUserNo());
        borrower.setOpUserName(loginUserInfo.getUserName());
        borrower.setOpTime(LocalDateTime.now());
        borrowerDao.updateStatus(borrower);
    }

    @Override
    public void updateDelete(BorrowerDeleteUpdateParam param) {
        UserSessionData loginUserInfo = TokenUtil.getLoginUserInfo();

        Borrower borrower = borrowerDao.getEntityByKey(param.getId()).orElseThrow(PerformanceResultEnum.DATA_NOT_FIND);
        if (Objects.equals(borrower.getStatus(), BorrowerEnum.Status.ENABLE.getCode())){
            throw new ServiceSystemException(PerformanceResultEnum.BORROWER_DELETE_ENABLE_ERROR);
        }

        borrower.setDeleteStatus(BorrowerEnum.DeleteStatus.YES.getCode());
        borrower.setOpUserNo(loginUserInfo.getUserNo());
        borrower.setOpUserName(loginUserInfo.getUserName());
        borrower.setOpTime(LocalDateTime.now());
        borrowerDao.updateDelete(borrower);
    }

    @Override
    public IPage<BorrowerVO> pageBorrower(PageBorrowerParam param) {
        return borrowerDao.pageByParam(param);

    }

    @Override
    public List<BorrowerVO> ListBorrower() {
        return borrowerStruct.convert(borrowerDao.listEnable());
    }

}
