package cn.pluss.platform.impl;

import cn.pluss.platform.IdCardService;
import cn.pluss.platform.dto.AccountDTO;
import cn.pluss.platform.entity.*;
import cn.pluss.platform.exception.MsgException;
import cn.pluss.platform.mapper.IdCardMapper;
import cn.pluss.platform.merchant.AccountService;
import cn.pluss.platform.merchant.MerchantBaseInfoService;
import cn.pluss.platform.merchantChannelStatus.MerchantChannelStatusService;
import cn.pluss.platform.userApp.UserAppService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Objects;

/**
 * <p>
 * 身份证信息表, 图片信息在tb_pluss_merchant_image表中 服务实现类
 * </p>
 *
 * @author Djh
 * @since 2020-10-16
 */
@RequiredArgsConstructor
@Service
public class IdCardServiceImpl extends ServiceImpl<IdCardMapper, IdCard> implements IdCardService {

    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantBaseInfoService mbiService;

    @Setter(onMethod_ = {@Lazy, @Autowired})
    private UserAppService userAppService;

    @Setter(onMethod_ = {@Lazy, @Autowired})
    private AccountService accountService;

    @Setter(onMethod_ = {@Lazy, @Autowired})
    private MerchantChannelStatusService mcsService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveOrUpdate(IdCard entity) {
        if (entity.getUserId() == null) {
            throw new MsgException("缺少用户id");
        }

        if (IdCard.TYPE_CERT.equals(entity.getUserType())) {
            return apiSaveCertIdCard(entity);
        }

        if (IdCard.TYPE_LEGAL.equals(entity.getUserType())) {
            return apiSaveLegalIdCard(entity);
        }

        Account account = new Account().setUserId(entity.getUserId()).setChannelType(Account.CHANNEL_TYPE_D1);
        account = accountService.getOne(new QueryWrapper<>(account));
        if (account != null) {
            entity.setId(Integer.parseInt(account.getIdCardId()));
        } else {
            // 清理所有残留数据
            IdCard exist = new IdCard()
                    .setUserId(entity.getUserId())
                    .setUserType(entity.getUserType());
            remove(new QueryWrapper<>(exist));
        }

        return super.saveOrUpdate(entity);
    }

    @Override
    public boolean apiSaveCertIdCard(IdCard entity) {
        UserApp userApp = new UserApp().setUserId(Long.parseLong(entity.getUserId()));
        userApp = userAppService.queryUserApp(userApp);
        if (IdCard.TYPE_CERT.equals(entity.getUserType())) {
            // 实名身份app只能提交一次
            String certNo = entity.getCertNo();
            IdCard exist = new IdCard().setCertNo(certNo);
            exist.setUserId(entity.getUserId());
            exist.setUserType(IdCard.TYPE_CERT);
            exist = getOne(new QueryWrapper<>(exist));
            Integer status = userApp.getStatus();
            boolean editFlag = status == null || (status != 3 && status != 1) || exist == null;

            MsgException.check(!editFlag, "修改实名身份证信息请联系客服");
        }

        return super.saveOrUpdate(entity);
    }

    @Override
    public boolean apiSaveLegalIdCard(IdCard entity) {
        // 法人身份证需要校验名称与营业执照上的名称是否一直
        MerchantBaseInfo mbi = mbiService.getMerchantBaseInfoByUserId(entity.getUserId());
        MsgException.checkUnequals(mbi.getPrincipalPerson(), entity.getCertName(), "【法人身份】与【营业执照所属人】不一致, 请核对信息后重新提交");

        UserApp tokenUa = userAppService.queryUserAppByToken();

        final IdCard certIdCard = getCertIdCard(entity.getUserId());
        if (!Objects.equals(certIdCard.getCertNo(), entity.getCertNo())
                || !Objects.equals(certIdCard.getCertName(), entity.getCertName()) ) {
            throw new MsgException("【法人信息】应与【实名身份信息】保持一致");
        }

        LambdaQueryWrapper<MerchantChannelStatus> qMcsWrapper = Wrappers.lambdaQuery();
        qMcsWrapper.eq(MerchantChannelStatus::getMerchantCode, tokenUa.getMerchantCode());
        qMcsWrapper.in(MerchantChannelStatus::getStatus,
                MerchantChannelStatus.AUDIT_STATUS_EXAMINING,
                MerchantChannelStatus.AUDIT_STATUS_SUCCESS,
                MerchantChannelStatus.AUDIT_STATUS_WAITING_SIGN,
                MerchantChannelStatus.AUDIT_STATUS_SIGNED);
        MerchantChannelStatus mcs = mcsService.getOne(qMcsWrapper.last("limit 1"));

        MsgException.checkNonNull(mcs, "当前状态暂不支持修改商户信息");

        IdCard exist = getLegalIdCard(entity.getUserId());
        if (exist != null) {
            entity.setId(exist.getId());
        }

        return super.saveOrUpdate(entity);
    }

    @Override
    public IdCard getCertIdCard(Object userId) {
        LambdaQueryWrapper<IdCard> qWrapper = Wrappers.lambdaQuery();
        qWrapper.eq(IdCard::getUserType, IdCard.TYPE_CERT)
                .eq(IdCard::getUserId, userId);
        return baseMapper.selectOne(qWrapper);
    }

    @Override
    public IdCard getLegalIdCard(String userId) {
        IdCard idCard = new IdCard();
        idCard.setUserId(userId);
        idCard.setUserType(IdCard.TYPE_LEGAL);
        idCard = getOne(new QueryWrapper<>(idCard));

        return idCard;
    }

    @Override
    public IdCard getReckonerIdCard(String userId, String merchantType) {
        if ("1".equals(merchantType)) {
            IdCard idCard = new IdCard();
            idCard.setUserId(userId);
            idCard.setUserType(IdCard.TYPE_ACCOUNT);
            idCard = getOne(new QueryWrapper<>(idCard));

            return idCard;
        }
        AccountDTO realAccount = accountService.getRealAccount(userId);
        if (realAccount != null) {
            return realAccount.getIdcard();
        }

        return null;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public IdCard createLegalIdCard(String userId) {
        IdCard legalIdCard = getLegalIdCard(userId);
        IdCard certIdCard = getCertIdCard(userId);
        if (legalIdCard != null && certIdCard.getCertNo().equals(legalIdCard.getCertNo())) {
            return legalIdCard;
        }

        MerchantBaseInfo merchantBaseInfo = new MerchantBaseInfo().setUserId(userId);
        merchantBaseInfo = mbiService.queryMerchantBaseInfo(merchantBaseInfo);

        if (merchantBaseInfo == null || "1".equals(merchantBaseInfo.getMerchantType())) {
            throw new MsgException("只有个体或企业商户具备法人信息");
        }

        if (!merchantBaseInfo.getPrincipalPerson().equals(certIdCard.getCertName())) {
            throw new MsgException("法人应与营业执照上的负责人相同");
        }

        legalIdCard = certIdCard;


        legalIdCard.setId(null);
        legalIdCard.setUserType(IdCard.TYPE_LEGAL);

        saveOrUpdate(legalIdCard);

        return legalIdCard;
    }

    @Override
    public IdCard apiGetFaceCertInfo() {
        final UserApp ua = userAppService.queryUserAppByToken();
        return getCertIdCard(ua.getUserId());
    }

}