package cn.iocoder.yudao.module.system.service.bank;

import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.bank.vo.UserBankSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.BankDO;
import cn.iocoder.yudao.module.system.dal.dataobject.bank.UserBankDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.bank.BankMapper;
import cn.iocoder.yudao.module.system.dal.mysql.bank.UserBankMapper;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertList;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 用户银行卡信息 Service 实现类
 *
 * @author 符溶馨
 */
@Service
@Validated
public class UserBankServiceImpl implements UserBankService {

    @Resource
    private UserBankMapper userBankMapper;

    @Resource
    private BankMapper bankMapper;

    @Resource
    private AdminUserService adminUserService;

    @Override
    public Long createBank(UserBankSaveReqVO createReqVO) {

        //校验银行卡号是否已存在
        Long count = bankMapper.selectCount(BankDO::getBankNo, createReqVO.getBankNo());
        if (count > 0L) {
            throw exception(BANK_EXISTS);
        }

        // 插入
        BankDO bank = BeanUtils.toBean(createReqVO, BankDO.class);
        bankMapper.insert(bank);
        // 返回
        return bank.getId();
    }

    @Override
    public void createPayBank(UserBankSaveReqVO createReqVO) {

        //校验银行卡号是否已存在
        BankDO bankDO = bankMapper.selectOne(BankDO::getBankNo, createReqVO.getBankNo());
        if (bankDO != null) {

            UserBankDO userBankDO = userBankMapper.selectByBankId(getLoginUserId(), bankDO.getId());
            if (userBankDO == null) {

                userBankDO = new UserBankDO();
                userBankDO.setUserId(getLoginUserId());
                userBankDO.setBankId(bankDO.getId());
                userBankDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());

                userBankMapper.insert(userBankDO);
            }
        }else {

            // 插入
            BankDO bank = BeanUtils.toBean(createReqVO, BankDO.class);
            bankMapper.insert(bank);

            UserBankDO userBankDO = new UserBankDO();
            userBankDO.setUserId(getLoginUserId());
            userBankDO.setBankId(bank.getId());
            userBankDO.setCreator(Objects.requireNonNull(getLoginUserId()).toString());

            userBankMapper.insert(userBankDO);
        }
    }

    @Override
    public void createUserBank(List<Long> bankId) {

        //获取当前登录用户信息
        AdminUserDO adminUserDO = adminUserService.getUser(getLoginUserId());

        List<UserBankDO> useDOs = bankId.stream()
                .map(id -> {
                    UserBankDO userBankDO = new UserBankDO();
                    userBankDO.setUserId(adminUserDO.getId());
                    userBankDO.setBankId(id);
                    userBankDO.setCreator(String.valueOf(adminUserDO.getId()));
                    return userBankDO;
                }).collect(Collectors.toList());

        userBankMapper.insertBatch(useDOs);
    }

    @Override
    public void updateBank(UserBankSaveReqVO updateReqVO) {
        // 校验存在
        validateBankExists(updateReqVO.getId());

        // 更新
        BankDO updateObj = BeanUtils.toBean(updateReqVO, BankDO.class);
        bankMapper.updateById(updateObj);
    }

    @Override
    public void deleteUserBank(Long id) {
        // 校验存在
        UserBankDO userBankDO = userBankMapper.selectByBankId(getLoginUserId(), id);
        if (userBankDO == null) {
            throw exception(BANK_NOT_EXISTS);
        }

        // 删除
        userBankMapper.deleteById(userBankDO);

        BankDO bankDO = bankMapper.selectById(userBankDO.getBankId());
        //校验当前登录用户是否是 该银行卡信息的创建者
        if (bankDO.getCreator().equals(userBankDO.getUserId().toString())) {

            // 同步删除 银行卡信息
            bankMapper.deleteById(bankDO.getId());
        }
    }

    private void validateBankExists(Long id) {

        BankDO bankDO = bankMapper.selectById(id);

        if (bankDO == null) {
            throw exception(BANK_NOT_EXISTS);
        }

        //校验当前登录用户是否是 该银行卡信息的创建者
        if (!Long.valueOf(bankDO.getCreator()).equals(getLoginUserId())) {
            throw exception(BANK_NOT_CREATOR);
        }
    }

    @Override
    public BankDO getBank(Long id) {

        return bankMapper.selectById(id);
    }

    @Override
    public List<Long> getBankIds(Long userId) {

        List<UserBankDO> userBankDOS = userBankMapper.selectList(UserBankDO::getUserId, userId);

        return convertList(userBankDOS, UserBankDO::getBankId);
    }

    @Override
    public PageResult<BankDO> getBankPageIn(UserBankPageReqVO pageReqVO, List<Long> bankId) {

        return bankMapper.selectPageIn(pageReqVO, bankId);
    }

    @Override
    public PageResult<BankDO> getBankPageNotIn(UserBankPageReqVO pageReqVO, List<Long> bankId) {

        return bankMapper.selectPageNotIn(pageReqVO, bankId);
    }

    @Override
    public List<BankDO> getBankListByUserId(Long userId) {

        if (getBankIds(userId).isEmpty()) {

            return null;
        }

        return bankMapper.selectBankList(getBankIds(userId));
    }
}