package com.manage.controller;


import com.alibaba.fastjson.JSONObject;
import com.manage.encrypt.Base64;
import com.manage.encrypt.MD5;
import com.manage.entity.Power_Dept;
import com.manage.entity.Power_Menu;
import com.manage.service.Power_DeptService;
import com.manage.service.Power_MenuService;
import com.manage.service.Power_UserService;
import com.manage.service.cache.Cache;
import com.manage.service.cache.CacheManager;
import com.manage.service.webSocket.WsPool;
import com.manage.util.ActionScopeUtils;
import com.manage.util.DateUtils;
import com.manage.util.Msg;
import com.manage.vo.Power_UserVo;
import com.manage.vo.User_Dept_Menu;
import org.apache.commons.lang3.StringUtils;
import org.apache.cxf.endpoint.Client;
import org.apache.cxf.jaxws.endpoint.dynamic.JaxWsDynamicClientFactory;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.utils.HttpClientUtils;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.*;

/**
 * Author xuhx
 * Date 2021/7/1
 * Time 16:39
 * Description 供无纸化归档使用的接口
 * Description 建党100周年纪念日
 */
@Controller
@RequestMapping("ssoLogin/")
public class SsoLogin {
    private static Logger logger = LoggerFactory.getLogger(HttpClientUtils.class); // 日志记录

    private static RequestConfig requestConfig = null;

    static {
        // 设置请求和传输超时时间
        requestConfig = RequestConfig.custom().setSocketTimeout(600000).setConnectTimeout(600000).build();
    }

    @Autowired
    Power_UserService powerUserService;

    @Autowired
    private Power_MenuService powerMenuService;

    @Autowired
    private Power_DeptService power_deptService;

    @Value("${EMRMEDICALRECORD_IP}")
    private String ip;

    @Value("${EMRMEDICALRECORD_PORT}")
    private String port;

    @Value("${TOKEN_EXPIRE_TIME}")
    private long TOKEN_EXPIRE_TIME;

    @Value("${oidc_address}")
    private String oidcAddress;

    @Value("${token_endpoint}")
    private String tokenEendpoint;

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

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

    @Value("${userinfo_endpoint}")
    private String userinfoEndpoint;

    @Value("${authorization_endpoint}")
    private String authorizationEndpoint;

    @Value("${URL_ADDRESS}")
    private String urlAddress;


    /*
     * 单点登录
     * author xuhx
     * */
    @RequestMapping(value = "login",method = RequestMethod.GET,produces = "text/html;charset=utf-8")
    @ResponseBody
    public String login(HttpServletRequest request,HttpServletResponse response,String code,String state) throws Exception {
        String result = "";
        CloseableHttpResponse responseNew = null;
        CloseableHttpClient httpClient = null;
        JSONObject jsonResultToken = null;
        String url=oidcAddress+tokenEendpoint;
        String StringUrl = URLEncoder.encode(urlAddress, "GBK");
        Map paramMap = new HashMap();
        paramMap.put("client_id",clientId);
        paramMap.put("client_secret",clientSecret);
        paramMap.put("code",code);
        paramMap.put("grant_type","authorization_code");
        paramMap.put("redirect_uri",urlAddress);
        String param="client_id="+clientId+"&client_secret="+clientSecret+"&code="+code+"&grant_type=authorization_code&redirect_uri="+StringUrl;
        String returnObject =doPost(url,paramMap,null);
        String userName="";
        if(returnObject!=null){
            // 把json字符串转换成json对象
            jsonResultToken = JSONObject.parseObject(returnObject);
            String accessToken=jsonResultToken.getString("access_token");
                    // 通过址默认配置创建一个httpClient实例
                    httpClient = HttpClients.createDefault();
                    // 创建httpGet远程连接实例
                    String userUrl=oidcAddress+userinfoEndpoint;
                    HttpGet httpGet = new HttpGet(userUrl);
                    // 设置请求头信息，鉴权
                    httpGet.setHeader("Authorization", "Bearer "+accessToken);
                    httpGet.setConfig(requestConfig);
                    // 执行get请求得到返回对象
                    responseNew = httpClient.execute(httpGet);
                    // 通过返回对象获取返回数据
                    HttpEntity entity = responseNew.getEntity();
                    // 通过EntityUtils中的toString方法将结果转换为字符串
                    String returnResult = EntityUtils.toString(entity);
                    // 把json字符串转换成json对象
                    JSONObject jsonResult = JSONObject.parseObject(returnResult);
                    if(jsonResult!=null){
                        /*if((jsonResult.getString("username"))!=null&&!"".equals(jsonResult.getString("username"))) {
                            userName=jsonResult.getString("username");
                        }*/
                        if((jsonResult.getString("name"))!=null&&!"".equals(jsonResult.getString("name"))) {
                            //接口返回的登录名为4位，我们系统为6位，接口登录名前追加两个0变成我们的6位
                            userName="00"+jsonResult.getString("name");
                            //根据登录名获取用户（需要确保用户登录名唯一）
                            Power_UserVo user = powerUserService.selectByUserName(userName);
                            if (user != null) {
                                String password = MD5.JM(Base64.decode(user.getUserPwd()));
                                if (password != null && !"".equals(password)) {
                                    //加密（此部分代码来自FontController的getToken方法，用来获取token及相关操作）
                                    String token = UUID.randomUUID().toString();
                                    List<Power_Menu> list = null;
                                    List<User_Dept_Menu> menuList = new ArrayList<>();
                                    Set<String> menus = new TreeSet<>();
                                    if (user.getRoleId().equals(0) || user.getRoleId().equals(-100)) {
                                        list = powerMenuService.queryAllPowerMenu(null,user.getRoleId());
                                    } else {
                                        list = powerMenuService.selectUserAndRoleMenuListPower(user.getUserId(),null);
                                    }
                                    if(null != list && !list.isEmpty()){
                                        for (Power_Menu power_menu : list) {
                                            User_Dept_Menu deptMenu = new User_Dept_Menu();
                                            String menuUrl = power_menu.getMenuUrl();
                                            if (StringUtils.isNotBlank(menuUrl)) {
                                                BeanUtils.copyProperties(power_menu, deptMenu);
                                                deptMenu.setMethodParent(power_menu.getParentId());
                                                menuList.add(deptMenu);
                                            }
                                            if (StringUtils.isNotBlank(power_menu.getMethod())) {
                                                menus.add(power_menu.getMenuUrl());
                                            }
                                        }
                                    }
                                    user.setMenuList(menuList);
                                    user.setMenus(menus);

                                    //设置科室
                                    StringBuilder powerDepts = new StringBuilder();
                                    List<Power_Dept> powerDeptsList = power_deptService.selectByPrimaryKeys(user.getDeptId());
                                    for(int j=0;j<powerDeptsList.size();j++){
                                        if(j<powerDeptsList.size()-1){
                                            powerDepts.append(powerDeptsList.get(j).getDeptName()).append(",");
                                        }else{
                                            powerDepts.append(powerDeptsList.get(j).getDeptName());
                                        }
                                    }
                                    user.setRemark(powerDepts.toString());
                            //移除缓存
                            /*CacheManager.removeCacheByObject(user);
                            CacheManager.putCache(date,new Cache(date,user,TOKEN_EXPIRE_TIME));*/
                                    ActionScopeUtils.setSessionAttribute("token",token,Integer.valueOf(String.valueOf(TOKEN_EXPIRE_TIME)));
                                    ActionScopeUtils.setSessionAttribute("CURRENT_USER",user,Integer.valueOf(String.valueOf(TOKEN_EXPIRE_TIME)));
                                    CacheManager.putCache(token,new Cache(user,System.currentTimeMillis(),TOKEN_EXPIRE_TIME*1000));

                                    if (!"".equals(token)&&token!=null) {
                                        //返回跳转url
                                        result="http://"+ip+":"+port+"/emr_medical_record/login?token=" + token + "&userName="+userName;
                                        //request.getRequestDispatcher(result).forward(request, response);
                                        response.sendRedirect(result);
                                    } else {
                                        result = "获取登录token失败，请检查数据!!";
                                    }
                                } else {
                                    result = "无法获取用户密码!!";
                                }
                            } else {
                                result = "登录用户不存在!!";
                            }
                        }
                        }else{
                        result = "SSO平台未成功返回用户信息!!";
                    }
            }
            return result;
        }
    @RequestMapping(value = "into",method = RequestMethod.GET,produces = "text/html;charset=utf-8")
    @ResponseBody
   public void in(HttpServletRequest request, HttpServletResponse response){
    //本项目中接收返回数据的地址
       String StringUrl = null;
       try {
           StringUrl = URLEncoder.encode(urlAddress, "GBK");
           try {
               response.sendRedirect(oidcAddress+authorizationEndpoint+"?client_id="+clientId+"&redirect_uri="+StringUrl+"&response_type=code&state="+1+"&scope=openid%20profile");
           } catch (IOException e) {
               e.printStackTrace();
           }
       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       }

   }

    public static String doPost(String url, Map<String, Object> paramMap, Map<String, String> headerMap) {

        CloseableHttpClient httpClient = null;
        CloseableHttpResponse httpResponse = null;
        String result = "";
        // 创建httpClient实例
        httpClient = HttpClients.createDefault();

        // 创建httpPost远程连接实例
        HttpPost httpPost = new HttpPost(url);
        RequestConfig requestConfig = null;
        // 配置请求参数实例
        requestConfig = RequestConfig.custom().setConnectTimeout(35000)// 设置连接主机服务超时时间
                .setConnectionRequestTimeout(35000)// 设置连接请求超时时间
                .setSocketTimeout(60000)// 设置读取数据连接超时时间
                .build();

        // 为httpPost实例设置配置
        //httpPost.setConfig(requestConfig);
        // 设置请求头
        if (headerMap == null){
            httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");// "application/json"
        } else {
            for (String key : headerMap.keySet()) {
                httpPost.addHeader(key, headerMap.get(key));
            }
        }

        // 封装post请求参数
        if (null != paramMap && paramMap.size() > 0) {
            List<NameValuePair> nvps = new ArrayList<>();
            // 通过map集成entrySet方法获取entity
            Set<Map.Entry<String, Object>> entrySet = paramMap.entrySet();
            // 循环遍历，获取迭代器
            Iterator<Map.Entry<String, Object>> iterator = entrySet.iterator();
            while (iterator.hasNext()) {
                Map.Entry<String, Object> mapEntry = iterator.next();
                nvps.add(new BasicNameValuePair(mapEntry.getKey(), mapEntry.getValue().toString()));
            }

            // 为httpPost设置封装好的请求参数
            try {
                httpPost.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        }
        try {
            // httpClient对象执行post请求,并返回响应参数对象
            httpResponse = httpClient.execute(httpPost);
            // 从响应对象中获取响应内容
            HttpEntity entity = httpResponse.getEntity();
            result = EntityUtils.toString(entity);
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (null != httpResponse) {
                try {
                    httpResponse.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != httpClient) {
                try {
                    httpClient.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;
    }

    /**
     * @MethodName sendMessage
     * @Description: 获取用户信息
     */
    @RequestMapping(value ="getUser",method = RequestMethod.GET)
    @ResponseBody
    public Power_UserVo sendMessage(String userName) throws Exception{
        return powerUserService.selectByUserName(userName);
    }

}
