package com.tiesheng.login.controller;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.core.util.URLUtil;
import com.alibaba.fastjson.JSON;
import com.tiesheng.annotation.token.TokenIgnore;
import com.tiesheng.login.config.token.TsTokenConfig;
import com.tiesheng.login.config.token.bean.TokenBean;
import com.tiesheng.login.pojos.dto.UniqueIndexDTO;
import com.tiesheng.login.service.LoginService;
import com.tiesheng.platform.config.ding.PlatformDingConfig;
import com.tiesheng.platform.config.ding.bean.DingJsapiSignature;
import com.tiesheng.platform.config.ding.bean.DingUserInfo;
import com.tiesheng.platform.config.wxmp.PlatformWxmpConfig;
import com.tiesheng.platform.config.wxmp.bean.WxJsapiSignature;
import com.tiesheng.platform.config.wxmp.bean.WxUserInfo;
import com.tiesheng.util.exception.ApiException;
import com.tiesheng.util.pojos.ApiResp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.Charset;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;

/**
 * @author hao
 */
@RestController
@RequestMapping("/login")
public class LoginController {


    @Autowired
    PlatformWxmpConfig platformWxmpConfig;
    @Autowired
    PlatformDingConfig platformDingConfig;
    @Autowired
    LoginService loginService;
    @Autowired
    TsTokenConfig tsTokenConfig;


    /**
     * 唯一值登录方式，如学号，手机号等
     *
     * @return
     */
    @GetMapping("/unique/redirect")
    @TokenIgnore
    public void uniqueIndex(UniqueIndexDTO dto, HttpServletResponse response) {
        loginService.checkLoginConfigurer(s -> {
            TokenBean tokenBean = s.doLogin("unique_index_" + dto.getPlatform(),
                    dto.getNo(), dto.getPlatform(), dto.getInfo());
            s.onLoginRedirect(tokenBean, dto.getExtra(), response);
        });
    }


    /**
     * 授权登录
     *
     * @param dto
     * @return
     */
    @PostMapping("/unique/index")
    @TokenIgnore
    public ApiResp<String> uniqueIndex(@RequestBody UniqueIndexDTO dto) {
        AtomicReference<TokenBean> tokenBeanAtomicReference = new AtomicReference<>();
        loginService.checkLoginConfigurer(s -> {
            tokenBeanAtomicReference.set(s.doLogin("unique_index_" + dto.getPlatform(),
                    dto.getNo(), dto.getPlatform(), dto.getInfo()));
        });
        TokenBean tokenBean = tokenBeanAtomicReference.get();
        if (tokenBean == null) {
            throw new ApiException("登录失败");
        }
        return ApiResp.respOK(tokenBean.toToken());
    }


    ///////////////////////////////////////////////////////////////////////////
    // 钉钉相关授权
    ///////////////////////////////////////////////////////////////////////////

    /**
     * 钉钉授权登录
     *
     * @param service
     * @param extra
     * @param response
     */
    @GetMapping("/ding/index/{service}")
    @TokenIgnore
    public void dingIndex(@PathVariable String service, String extra, HttpServletResponse response) {
        if (StrUtil.isEmpty(extra)) {
            extra = "";
        }
        Map<String, String> map = MapUtil.newHashMap();
        map.put("corpId", platformDingConfig.getConfigBean(service).getCorpId());
        map.put("service", service);
        map.put("extra", extra);
        loginService.checkLoginConfigurer(s -> {
            String query = URLUtil.buildQuery(map, Charset.defaultCharset());
            String configUrl = loginService.buildPath("/ding/index.html?" + query);
            try {
                response.sendRedirect(configUrl);
            } catch (IOException ignored) {
            }
        });
    }


    /**
     * 钉钉授权回调
     *
     * @param service
     */
    @RequestMapping("/ding/oauth2/{service}")
    @TokenIgnore
    public void dingOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
        loginService.checkLoginConfigurer(configurer -> {
            String ddUserId = platformDingConfig.getUserIdByCode(service, code);
            DingUserInfo dingUserInfo = platformDingConfig.topapiV2UserGet(service, ddUserId);
            TokenBean tokenBean = configurer.doLogin(dingUserInfo.getAppId(), dingUserInfo.getUserid(), "ding",
                    JSON.toJSONString(dingUserInfo));
            configurer.onLoginRedirect(tokenBean, extra, response);
        });
    }


    /**
     * 钉钉授权jssdk
     *
     * @param url
     * @return
     */
    @GetMapping("/ding/jssdk/{service}")
    @TokenIgnore
    public ApiResp<DingJsapiSignature> dingJssdk(@PathVariable String service, String url) {
        DingJsapiSignature jsapiSignature = platformDingConfig.createJsapiSignature(service, url);
        return ApiResp.respOK(jsapiSignature);
    }


    ///////////////////////////////////////////////////////////////////////////
    // 微信相关
    ///////////////////////////////////////////////////////////////////////////


    /**
     * 微信授权登录
     *
     * @return
     */
    @RequestMapping("/wxmp/index/{service}")
    @TokenIgnore
    public void wxmpIndex(@PathVariable String service, String extra, HttpServletResponse response) throws IOException {
        if (StrUtil.isEmpty(extra)) {
            extra = "";
        }
        String configUrl = loginService.buildPath("/auth/wxmp/oauth2/" + service + "?extra=" + extra);
        String authorizationUrl = platformWxmpConfig.buildAuthorizationUrl(service, configUrl, "snsapi_userinfo");
        response.sendRedirect(authorizationUrl);
    }


    /**
     * 微信授权回调
     *
     * @param code
     */
    @RequestMapping("/wxmp/oauth2/{service}")
    @TokenIgnore
    public void wxmpOauth2(@PathVariable String service, String code, String extra, HttpServletResponse response) {
        loginService.checkLoginConfigurer(configurer -> {
            WxUserInfo wxUserInfo = platformWxmpConfig.getOAuth2AccessToken(service, code);
            TokenBean tokenBean = configurer.doLogin(wxUserInfo.getAppId(), wxUserInfo.getOpenid(), "wxmp", JSON.toJSONString(wxUserInfo));
            configurer.onLoginRedirect(tokenBean, extra, response);
        });
    }


    /**
     * 微信授权jssdk
     *
     * @param url
     * @return
     */
    @GetMapping("/wxmp/jssdk/{service}")
    @TokenIgnore
    public ApiResp<WxJsapiSignature> wxmpJssdk(@PathVariable String service, String url) {
        WxJsapiSignature jsapiSignature = platformWxmpConfig.createJsapiSignature(service, url);
        return ApiResp.respOK(jsapiSignature);
    }


}
