package cn.com.poc.user.builder;

import cn.com.poc.common.utils.Assert;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.equity.aggregate.MemberEquityService;
import cn.com.poc.user.dto.MemberLoginRequestDto;
import cn.com.poc.user.entity.MemberInfoEntity;
import cn.com.poc.user.query.CheckMemberInfoQueryCondition;
import cn.com.poc.user.query.CheckMemberInfoQueryItem;
import cn.com.poc.user.service.BizMemberInfoService;
import cn.com.poc.user.wecom.constant.WecomConstant;
import cn.com.poc.user.wecom.domain.WecomUserProfile;
import cn.com.poc.user.wecom.service.WecomLoginService;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import cn.com.yict.framemax.frame.service.FmxParamConfigService;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

@Service
public class WecomLoginChannel implements LoginChannelService {

    @Resource
    private WecomLoginService wecomLoginService;

    @Resource
    private BizMemberInfoService bizMemberInfoService;

    @Resource
    private MemberEquityService memberEquityService;

    @Resource
    private FmxParamConfigService fmxParamConfigService;

    @Override
    public MemberInfoEntity doLogin(MemberLoginRequestDto memberLoginRequest) throws Exception {
        Assert.notBlank(memberLoginRequest.getAuthCode());
        Assert.notBlank(memberLoginRequest.getLoginType(), "loginType");

        WecomUserProfile profile = wecomLoginService.getUserProfile(memberLoginRequest.getAuthCode(), memberLoginRequest.getLoginType());
        if (profile == null) {
            throw new I18nMessageException("exception/system.error");
        }

        MemberInfoEntity member = findExistingMember(profile);
        if (member != null) {
            return member;
        }

        return registerByWecom(profile);
    }

    private MemberInfoEntity findExistingMember(WecomUserProfile profile) throws Exception {
        if (StringUtils.isNotBlank(profile.getMobile())) {
            MemberInfoEntity member = findByMobile(profile.getMobile());
            if (member != null) {
                return member;
            }
        }
        if (StringUtils.isNotBlank(profile.getEmail())) {
            MemberInfoEntity member = findByEmail(profile.getEmail());
            if (member != null) {
                return member;
            }
        }
        String account = buildWecomAccount(profile);
        if (StringUtils.isBlank(account)) {
            return null;
        }
        return bizMemberInfoService.getMemberEntityByAccount(account);
    }

    private MemberInfoEntity registerByWecom(WecomUserProfile profile) {
        String account = resolveAccount(profile);
        if (StringUtils.isBlank(account)) {
            throw new I18nMessageException("exception/system.error");
        }
        MemberInfoEntity memberInfoEntity = new MemberInfoEntity();
        memberInfoEntity.setAccount(account);
        memberInfoEntity.setNickName(StringUtils.defaultIfBlank(profile.getName(), account));
        memberInfoEntity.setAvatarUrl(resolveAvatar(profile.getAvatarUrl()));
        memberInfoEntity.setMobilePhone(profile.getMobile());
        memberInfoEntity.setEmail(profile.getEmail());
        MemberInfoEntity result = bizMemberInfoService.createMemberInfo(memberInfoEntity);
        try {
            memberEquityService.initMemberEquity(result.getMemberId().longValue());
        } catch (Exception e) {
            throw new I18nMessageException("exception/system.error");
        }
        return result;
    }

    private MemberInfoEntity findByMobile(String mobile) throws Exception {
        CheckMemberInfoQueryCondition condition = new CheckMemberInfoQueryCondition();
        condition.setMobilePhone(mobile);
        List<CheckMemberInfoQueryItem> items = bizMemberInfoService.checkMemberInfoIsExist(condition);
        if (CollectionUtils.isEmpty(items)) {
            return null;
        }
        return bizMemberInfoService.getById(items.get(0).getMemberId());
    }

    private MemberInfoEntity findByEmail(String email) throws Exception {
        CheckMemberInfoQueryCondition condition = new CheckMemberInfoQueryCondition();
        condition.setEmail(email);
        List<CheckMemberInfoQueryItem> items = bizMemberInfoService.checkMemberInfoIsExist(condition);
        if (CollectionUtils.isEmpty(items)) {
            return null;
        }
        return bizMemberInfoService.getById(items.get(0).getMemberId());
    }

    private String resolveAccount(WecomUserProfile profile) {
        if (StringUtils.isNotBlank(profile.getMobile())) {
            return profile.getMobile();
        }
        if (StringUtils.isNotBlank(profile.getEmail())) {
            return profile.getEmail();
        }
        return buildWecomAccount(profile);
    }

    private String resolveAvatar(String avatarUrl) {
        if (StringUtils.isNotBlank(avatarUrl)) {
            return avatarUrl;
        }
        return fmxParamConfigService.getParam("member.default.avatar");
    }

    private String buildWecomAccount(WecomUserProfile profile) {
        String userId = StringUtils.defaultIfBlank(profile.getUserId(), profile.getOpenUserId());
        if (StringUtils.isBlank(userId)) {
            return null;
        }
        String corpId = profile.getCorpId();
        if (StringUtils.isBlank(corpId)) {
            return WecomConstant.AccountPrefix.WECOM + userId;
        }
        return WecomConstant.AccountPrefix.WECOM + corpId + ":" + userId;
    }
}
