package com.dgtis.dorm.manager.admin.web;

import com.dgtis.dorm.manager.admin.dao.AdminToken;
import com.dgtis.dorm.manager.admin.service.AdminTokenManager;
import com.dgtis.dorm.manager.db.domain.Admin;
import com.dgtis.dorm.manager.db.service.AdminService;
import com.dgtis.dorm.manager.db.util.JacksonUtil;
import com.dgtis.dorm.manager.db.util.ResponseUtil;

import org.apache.commons.lang3.StringUtils;
import org.apache.oltu.oauth2.client.OAuthClient;
import org.apache.oltu.oauth2.client.URLConnectionClient;
import org.apache.oltu.oauth2.client.request.OAuthBearerClientRequest;
import org.apache.oltu.oauth2.client.request.OAuthClientRequest;
import org.apache.oltu.oauth2.client.response.OAuthAccessTokenResponse;
import org.apache.oltu.oauth2.client.response.OAuthResourceResponse;
import org.apache.oltu.oauth2.common.OAuth;
import org.apache.oltu.oauth2.common.message.types.GrantType;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.util.Assert;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Map;

/**
 * @descption:客户端Oauth登录
 * @auther: qxm
 * @date: 2019/6/3 11:28
 */
@Controller
@RequestMapping("/admin/oauthCtl")
public class OauthCtl {

    @Autowired
    private AdminService adminService;

    @Value("${SERVER_URL}")
    public String SERVER_URL ;
    //授权验证成功跳转路径
    @Value("${LOGIN_SUCCESS}")
    private String LOGIN_SUCCESS;
    //失败跳转路径
    @Value("${LOGIN_FAIL}")
    private String LOGIN_FAIL ;

    @Value("${client_id}")
    private String client_id;

    @Value("${client_secret}")
    private String client_secret ;

    @Value("${http_server_url}")
    private String http_server_url;

    @Value("${redirect_uri}")
    private String redirect_uri;

    @Value("${urlLoginByCode}")
    private String urlLoginByCode;//小程序后台的地址（要拼接code）

    /**
     * 重定向到服务端获取授权码
     *
     * @param request
     * @param response
     * @return
     * @throws Exception
     */
    @RequestMapping("pcOauth2toServer")
    public String oauth2toServer(HttpServletRequest request, HttpServletResponse response, RedirectAttributes attr) throws Exception {
        System.out.println("pcOauth2toServer==================");
        attr.addAttribute("client_id", client_id);
        attr.addAttribute("response_type", "code");
        attr.addAttribute("redirect_uri",redirect_uri);
        return "redirect:" + http_server_url +"/authorize.if"; //重定向
    }

    /**
     * 服务端回调服务，获取授权码，授权登录成功，跳转到主页面
     *
     * @param code 服务端回调获取的授权码
     */
    @RequestMapping("pcCallback")
    public String callback(HttpServletRequest request, @ModelAttribute("code") String code) throws Exception {
        System.out.println("pcCallback=====client authCode:" + code);
        return "redirect:" + urlLoginByCode +"?code="+code+"&loginstatus=true"; //带上code重定向到vue首页
    }

    /**
     * vue首页首页检测到code，直接根据code验证登录
     *
     * @param body 服务端回调获取的授权码
     */
    @RequestMapping("loginByCode")
    @ResponseBody
    public Object loginByCode(@RequestBody String body) throws Exception {
        String code = JacksonUtil.parseString(body, "code");
        System.out.println("client code:" + code);
        String employeNo = getAccreditByServer(code, redirect_uri);
        System.out.println("client employeNo:" + employeNo);
        if(StringUtils.isEmpty(employeNo)){
            return ResponseUtil.badArgument();
        }
        List<Admin> adminList = adminService.findByEno(employeNo);
        Assert.state(adminList.size() < 2, "同一个用户名存在两个账户");
        if(adminList.size() == 0){
            return ResponseUtil.badArgumentValue();
        }
        Admin admin = adminList.get(0);

        Integer adminId = admin.getId();
        // token
        AdminToken adminToken = AdminTokenManager.generateToken(adminId);

        return ResponseUtil.ok(adminToken.getToken());
    }

    public String getAccreditByServer(String authCode,String redirect_url) {
        //http://localhost:8080/web-oauth2-server/accessToken?client_id=c1ebe466-1cdc-4bd3-ab69-77c3561b9dee&client_secret=d8346ea2-6017-43ed-ad68-19c0f971738b&grant_type=authorization_code&code=12545716af0a62d4918d5a245d62b030&redirect_uri=http://test.dgtis.com:8080/web-base/system/MainCtr/initMain
        String accessTokenUrl = http_server_url+"/accessToken.if";
        OAuthClient oAuthClient = new OAuthClient(new URLConnectionClient());
        OAuthResourceResponse resourceResponse = null;

        try {
            //使用授权码获取accessToken
            OAuthClientRequest accessTokenRequest = OAuthClientRequest
                    .tokenLocation(accessTokenUrl)
                    .setGrantType(GrantType.AUTHORIZATION_CODE)
                    .setClientId(client_id)
                    .setClientSecret(client_secret)
                    .setCode(authCode)
                    .setRedirectURI(redirect_url)
                    .buildBodyMessage();
            OAuthAccessTokenResponse oAuthResponse = oAuthClient.accessToken(accessTokenRequest, OAuth.HttpMethod.POST);
            //获取到的token  scc
            String accessToken = oAuthResponse.getAccessToken();
            Long expiresIn = oAuthResponse.getExpiresIn();

            System.out.println("AccessToken Client : "+accessToken);

            //使用accessToken获取用户信息
            //http://test.dgtis.com:8080/web-base/userInfo?access_token=7921a463132b857e8d929061fb7b6902
            String userInfoUrl = http_server_url +"/userInfo.if";
            OAuthClientRequest userInfoRequest = new OAuthBearerClientRequest(userInfoUrl).setAccessToken(accessToken).buildQueryMessage();

            resourceResponse = oAuthClient.resource(userInfoRequest, OAuth.HttpMethod.GET, OAuthResourceResponse.class);

        }catch (Exception e){
            e.printStackTrace();
        }

        String userInfoRes = resourceResponse.getBody();
        System.out.println("UserInfo Client : "+userInfoRes);

        //Gson gson = new Gson();
        //Map<String,String> userInfo  = gson.fromJson(userInfoRes, Map.class);
        Map<String,String> userInfo  = JacksonUtil.parseObject(userInfoRes, Map.class);

        return userInfo.get("employeNo");
    }


}
