package cn.com.poc.user.wecom.rest.impl;

import cn.com.poc.common.utils.Assert;
import cn.com.poc.common.utils.StringUtils;
import cn.com.poc.support.security.oauth.constants.OauthConstants;
import cn.com.poc.user.builder.LoginChannelBuilder;
import cn.com.poc.user.constants.UserLoginConstants;
import cn.com.poc.user.dto.MemberLoginRequestDto;
import cn.com.poc.user.dto.MemberLoginResponseDto;
import cn.com.poc.user.entity.MemberInfoEntity;
import cn.com.poc.user.wecom.constant.WecomConstant;
import cn.com.poc.user.wecom.domain.WecomLoginUrlDto;
import cn.com.poc.user.wecom.domain.properties.WecomProperties;
import cn.com.poc.user.wecom.rest.WecomLoginRest;
import cn.com.poc.user.wecom.service.WecomComponentService;
import cn.com.yict.framemax.core.i18n.I18nMessageException;
import cn.com.yict.framemax.security.oauth.OauthAccesstokenManager;
import cn.com.yict.framemax.security.oauth.entity.OauthResultEntity;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;

@Component
public class WecomLoginRestImpl implements WecomLoginRest {

    @Resource
    private WecomProperties wecomProperties;

    @Resource
    private WecomComponentService wecomComponentService;

    @Resource
    private LoginChannelBuilder loginChannelBuilder;

    @Resource
    private OauthAccesstokenManager tokenManager;

    @Override
    public WecomLoginUrlDto getOauthUrl(String requestUrl, String scope, String state) throws Exception {
        String redirectUrl = StringUtils.isBlank(requestUrl) ? wecomProperties.getRedirectUrl() : requestUrl;
        String suiteId = wecomProperties.getSuiteId();
        Assert.notBlank(redirectUrl, "redirectUrl");
        Assert.notBlank(suiteId, "suiteId");

        String scopeValue = StringUtils.defaultIfBlank(scope, "snsapi_privateinfo");
        String stateValue = StringUtils.defaultIfBlank(state, WecomConstant.LoginType.WEB_PAGE_LOGIN);
        String oauthUrl = wecomComponentService.oauth2Authorize(suiteId, redirectUrl, "code", scopeValue, stateValue);

        WecomLoginUrlDto result = new WecomLoginUrlDto();
        result.setLoginType(WecomConstant.LoginType.WEB_PAGE_LOGIN);
        result.setUrl(oauthUrl);
        return result;
    }

    @Override
    public WecomLoginUrlDto getQrConnectUrl(String requestUrl, String userType, String state) throws Exception {
        String redirectUrl = StringUtils.isBlank(requestUrl) ? wecomProperties.getRedirectUrl() : requestUrl;
        String corpId = wecomProperties.getCorpId();
        Assert.notBlank(redirectUrl, "redirectUrl");
        Assert.notBlank(corpId, "corpId");

        String stateValue = StringUtils.defaultIfBlank(state, WecomConstant.LoginType.QR_CODE_LOGIN);
        String qrUrl = wecomComponentService.connectQrconnect(corpId, redirectUrl, userType, stateValue);

        WecomLoginUrlDto result = new WecomLoginUrlDto();
        result.setLoginType(WecomConstant.LoginType.QR_CODE_LOGIN);
        result.setUrl(qrUrl);
        return result;
    }

    @Override
    public MemberLoginResponseDto toLogin(String code, String loginType) throws Exception {
        Assert.notBlank(code, "code");
        Assert.notBlank(loginType, "loginType");

        MemberLoginRequestDto request = new MemberLoginRequestDto();
        request.setLoginChannel(UserLoginConstants.LoginType.MEMBER_PLATFOMR_WECOM);
        request.setAuthCode(code);
        request.setLoginType(loginType);

        MemberInfoEntity memberInfoEntity = (MemberInfoEntity) loginChannelBuilder
                .getService(request.getLoginChannel())
                .doLogin(request);
        if (memberInfoEntity == null) {
            throw new I18nMessageException("exception/system.error");
        }

        OauthResultEntity auth = tokenManager.auth(OauthConstants.TypePrefix.MEMBER_DOMAIN + memberInfoEntity.getMemberId(), null, null);
        MemberLoginResponseDto response = new MemberLoginResponseDto();
        response.setMemberId(memberInfoEntity.getMemberId());
        response.setNickName(memberInfoEntity.getNickName());
        response.setAvatarUrl(memberInfoEntity.getAvatarUrl());
        response.setMobilePhone(memberInfoEntity.getMobilePhone());
        response.setToken(auth.getToken());
        return response;
    }
}
