package com.songhua.framework.sso;


import com.songhua.common.core.domain.AjaxResult;
import com.songhua.common.core.domain.entity.SysUser;
import com.songhua.common.core.domain.model.LoginUser;
import com.songhua.common.utils.uuid.IdUtils;
import com.songhua.framework.sso.utli.AjaxJson;
import com.songhua.framework.sso.utli.MyHttpSessionHolder;
import com.songhua.framework.web.service.SysLoginService;
import com.songhua.framework.web.service.TokenService;
import com.songhua.system.service.impl.SysUserServiceImpl;
import org.apache.commons.lang3.ObjectUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@RestController
public class SsoLoginController {

    @Resource
    private SysUserServiceImpl sysUserServiceImpl;

    @Resource
    private SysLoginService sysLoginService;

    @Resource
    private TokenService tokenService;

    @Resource
    private SsoRequestUtil ssoRequestUtil;


    // 返回SSO认证中心登录地址 （前后台分离环境下专用）
    @RequestMapping("/sso/getSsoAuthUrl")
    public AjaxJson getSsoAuthUrl(String clientLoginUrl) {
        String serverAuthUrl = ssoRequestUtil.buildServerAuthUrl(clientLoginUrl);
        return AjaxJson.getSuccessData(serverAuthUrl);
    }

    // 根据ticket进行登录（前后台分离环境下专用）
    @RequestMapping("/sso/doLoginByTicket")
    public AjaxResult doLoginByTicket(String ticket, HttpServletRequest request) {
        Map map = new HashMap();
        HttpSession session = MyHttpSessionHolder.getSession(request);
        Object loginId = ssoRequestUtil.checkTicket(ticket, request, "/sso/doLoginByTicket");
        if(loginId != null) {
            session.setAttribute("userId", loginId);
            session.setAttribute("user", ssoRequestUtil.getUserInfo(loginId));
            /**此处处理一体化用户登录业务**/
            SysUser user = sysUserServiceImpl.selectUserById(Long.parseLong(loginId.toString()));//此处根据sso端用户唯一标识来换取客户端用户与唯一标识，不局限于用户ID，只要能和sso端的loginId对应即可
            if(ObjectUtils.isNotEmpty(user)){
                String token = sysLoginService.ssoLogin(user.getUserName());
                map.put("access_token", token);
                map.put("expires_in", 30);
                map.put("userinfo",user);
                map.put("session_id", session.getId());
            }
            return AjaxResult.success(map);
        }
        return AjaxResult.error("无效ticket：" + ticket);
    }

    // getInfo接口 （只有登录后才可以调用此接口）
    @RequestMapping("/getCurrInfo")
    public Object getCurrInfo(HttpServletRequest request) {
        // 如果没有登录，就返回特定信息
        HttpSession session = MyHttpSessionHolder.getSession(request);
        if(session.getAttribute("userId") == null) {
            return AjaxJson.getNotLogin();
        }
        // 从Session中获取user对象
        SysUser user = (SysUser) session.getAttribute("user");
        return AjaxJson.getSuccessData(user);
    }


    // SSO-Client端：单点注销地址
    @RequestMapping("/sso/logout")
    public Object ssoLogout(HttpServletRequest request, HttpServletResponse response) throws IOException {

        // 如果未登录，则无需注销
        HttpSession session = MyHttpSessionHolder.getSession(request);
        if(session.getAttribute("userId") == null) {
            return AjaxResult.success(ssoRequestUtil.getLogoutRedirectUrl());
        }

        // 调用 sso-server 认证中心单点注销API
        Object loginId = session.getAttribute("userId");  // 账号id
        String timestamp = String.valueOf(System.currentTimeMillis());	// 时间戳
        String nonce = ssoRequestUtil.getRandomString(20);		// 随机字符串
        String sign = ssoRequestUtil.getSign(loginId, timestamp, nonce, ssoRequestUtil.secretkey);	// 参数签名

        String url = ssoRequestUtil.getSloUrl() +
                "?loginId=" + loginId +
                "&timestamp=" + timestamp +
                "&nonce=" + nonce +
                "&sign=" + sign;
        AjaxJson result = ssoRequestUtil.request(url);

        // 校验响应状态码，200 代表成功
        if(result.getCode() == 200) {

            // 极端场景下，sso-server 中心的单点注销可能并不会通知到此 client 端，所以这里需要再补一刀
            session.removeAttribute("userId");
            // 如果指定了 back 地址，则重定向，否则返回 JSON 信息
            return AjaxResult.success("注销成功",ssoRequestUtil.getLogoutRedirectUrl());
//            if(SsoRequestUtil.isNotEmpty(back)) {
//                response.sendRedirect(back);
//                return null;
//            } else {
//                return AjaxJson.getSuccess();
//            }

        } else {
            // 将 sso-server 回应的消息作为异常抛出
            throw new RuntimeException(result.getMsg());
        }
    }
}
