package com.jeesite.modules.sso.service;


import com.alibaba.fastjson.JSON;
import com.jeesite.common.config.Global;
import com.jeesite.common.web.BaseController;
import com.jeesite.common.web.http.HttpClientUtils;
import com.jeesite.modules.sso.dao.SsoAppDao;
import com.jeesite.modules.sso.entity.SsoApp;
import com.jeesite.modules.sys.dao.UserDao;
import com.jeesite.modules.sys.entity.User;
import com.jeesite.modules.sys.service.UserService;
import com.jeesite.modules.sys.utils.UserUtils;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.RandomUtils;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.time.Duration;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
@Slf4j
public class SsoOauthService extends BaseController {
    @Autowired
    private RedisTemplate<String,String> redisTemplate;
    @Autowired
    private SsoAppService ssoAppService;
    @Autowired
    private SsoAppDao ssoAppDao;
    @Value("${jwt.secret}")
    private String secret;
    @Autowired
    private UserDao userDao;

    /***
     * 验证appkey和秘钥
     * @param appKey
     * @param appSecretkey
     * @param responseType  固定值填写code
     * @return
     */
    public String authorize(String appKey, String appSecretkey, String responseType, String redirectUri) {
        User user = UserUtils.getUser();
        if(appKey==null ){
            return renderResult(Global.FALSE,"您的appkey为空");
        }

        if(appSecretkey==null){
            return renderResult(Global.FALSE,"您的appSecretkey为空");
        }

        if(responseType==null){
            return renderResult(Global.FALSE,"您的responseType为空");
        }
        if(!responseType.equals("code")){
            return renderResult(Global.FALSE,"您的responseType类型错误");
        }
        if(redirectUri==null){
            return renderResult(Global.FALSE,"您的redirectUri为空");
        }
        //验证appkey和appSecretkey
        boolean check = checkPram(appKey, appSecretkey);
        if(check==false){
            return renderResult(Global.FALSE,"未验证通过的客户端身份,appSecretkey或appkey错误");
        }

        //生成code
        String code = user.getRefCode();
        //保存到redis中，设置15分钟过期
        String redisKey = "CHECK_CODE_" + appKey;
        this.redisTemplate.opsForValue().set(redisKey, code, Duration.ofMinutes(15));

        //发送请求
        if(!redirectUri.contains("http://") && !redirectUri.contains("https://")){
            redirectUri="http://"+redirectUri;
        }

        log.info("发送请求："+redirectUri+"?code="+code);
        return redirectUri+"?code="+code;
    }


    /***
     * 生成token
     * @param appKey
     * @param appSecretkey
     * @param grantType  固定值authorization_code
     * @param code  验证码需要去redis中验证
     * @return
     */
    public String getToken(String appKey, String appSecretkey, String grantType, String code) {
        //验证appkey和appSecretkey
        boolean check = checkPram(appKey, appSecretkey);
        if(check==false){
            return renderResult(Global.FALSE,"未验证通过的客户端身份,appSecretkey或appkey错误");
        }

        //去redis中验证code
        String redisKey = "CHECK_CODE_" + appKey;
        String redisData = redisTemplate.opsForValue().get(redisKey);
        if(redisData==null){
            return renderResult(Global.FALSE,"授权码已经失效");
        }
        if(!redisData.equals(code)){
            return renderResult(Global.FALSE,"授权码验证失败");
        }
        //验证成功后删除rediskey
        redisTemplate.delete(redisKey);
        Date date = new DateTime().plusHours(1).toDate();

        //生成token给用户返回
        HashMap<String,Object> claims=new HashMap<>();
        claims.put("appKey",appKey);
        claims.put("appSecretkey",appSecretkey);
        claims.put("userId",code);
        String token = Jwts.builder()
                .setClaims(claims) //payload，存放数据的位置，不能放置敏感数据，如：密码等
                .signWith(SignatureAlgorithm.HS256, secret) //设置加密方法和加密盐
                .setExpiration(date) //设置过期时间
                .compact();

        User user = UserUtils.getUser();
        //封装信息
        HashMap<String,String> result=new HashMap<>();
        result.put("access_token",token);
        result.put("expires_in",date.getTime()+"");
        result.put("result","true");
        String jsonString = JSON.toJSONString(result);
        return jsonString;
    }

    /**
     * 检查参数是否正确
     * @return
     */
    public boolean checkPram(String appKey,String appSecretkey){
        //判读appkey和appSecretkey是否正确
        SsoApp ssoApp = ssoAppDao.selectAppBykey(appKey);
        if(ssoApp==null){
            return false;
        }

        SsoApp ssoApp1 =ssoAppDao.selectAppBySecretkey(appKey,appSecretkey);
        if(ssoApp1==null){
            return false;
        }
        return true;
    }


    /***
     *  获取登录id
     * @return
     */
    public String getUserIdByToken(HttpServletRequest request, HttpServletResponse response) {
        String token = request.getHeader("Authorization");
        //解析token
        Map<String, Object> body = Jwts.parser()//加密盐值
                .setSigningKey(secret)    //
                .parseClaimsJws(token)  //前台传过来的token
                .getBody();
        //创建user对象
        String appKey = body.get("appKey").toString();
        String appSecretkey = body.get("appSecretkey").toString();
        String userId = body.get("userId").toString();

        boolean flag = checkPram(appKey, appSecretkey);
        if(flag==false){
            return renderResult(Global.FALSE,"未验证通过的客户端身份,appSecretkey或appkey错误");
        }
        HashMap<String,String> hashMap=new HashMap<>();
        //通过appkey查询要返回的
        User user=new User();
        user.setRefCode(userId);
        user.setStatus("0");
        user.setUserType("employee");
        User userRefCode = userDao.getByUserTypeAndRefCode(user);
        SsoApp ssoApp = ssoAppDao.selectAppBykey(appKey);
        String returnAttribute = ssoApp.getReturnAttribute();
        String[] split = returnAttribute.split(",");
        for (String s : split) {
            if(s.equals("1")){
                hashMap.put("userName",userRefCode.getUserName());
            }else if (s.equals("2")){
                hashMap.put("email",userRefCode.getEmail());
            }else if (s.equals("3")){
                hashMap.put("mobile",userRefCode.getPhone());
            }else if (s.equals("4")){
                hashMap.put("userId",userRefCode.getRefCode());
            }else if (s.equals("5")){
                hashMap.put("phone",userRefCode.getMobile());
            }
        }
        hashMap.put("result","true");
        String jsonString = JSON.toJSONString(hashMap);
        return jsonString;
    }



}
