package com.yihu.hos.common;

import com.fasterxml.jackson.core.type.TypeReference;
import com.yihu.ehr.agModel.app.AppFeatureModel;
import com.yihu.hos.common.constants.ContextAttributes;
import com.yihu.hos.core.http.HTTPResponse;
import com.yihu.hos.core.http.HttpClientKit;
import com.yihu.hos.remotemanage.service.RemoteShellService;
import com.yihu.hos.system.model.SystemUser;
import com.yihu.hos.tenant.model.TenantSession;
import com.yihu.hos.tenant.service.AuthenticateService;
import com.yihu.hos.web.framework.model.AccessToken;
import com.yihu.hos.web.framework.model.Envelop;
import com.yihu.hos.web.framework.model.EnvelopExt;
import com.yihu.hos.web.framework.util.controller.BaseController;
import io.swagger.annotations.ApiParam;
import org.apache.commons.io.IOUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.*;

/**
 * 数据采集配置页面
 * Created by hzp on 2015/8/12.
 */
@RequestMapping("/")
@Controller("commonPageController")
public class CommonPageController extends BaseController {

    @Value("${hos.administrators}")
    private String saasAdmin;
    @Value("${hos.clientId}")
    private String clientId;
    @Value("${service-gateway.adminUrl}")
    public String adminUrl;
    @Value("${service-gateway.portalUrl}")
    public String portalUrl;
    @Value("${service-gateway.oauth2authorize}")
    private String oauth2authUrl;

    @Autowired
    private AuthenticateService authenticateService;

    private RemoteShellService remoteShellService;

    @RequestMapping("testPage")
    public String initial(Model model) {
        model.addAttribute("contentPage", "/common/test");
        return "pageView";
    }

    /**
     *  租户授权失败跳转页面
     * @param model
     * @return
     */
    @RequestMapping("tenantAutoFail")
    public String tenantAutoFail(Model model) {
        model.addAttribute("contentPage", "/common/tenantAutoFail");
        return "pageView";
    }

    /**
     *  集成登录验证失败跳转页面
     * @param model
     * @return
     */
    @RequestMapping("/oauth2/tokenValidFail")
    public String tokenValidFail(Model model) {
        model.addAttribute("contentPage", "/common/tokenValidFail");
        return "pageView";
    }

    /*
    登录页面
     */
    @RequestMapping("loginPage")
    public String login(Model model, HttpServletRequest request, HttpServletResponse response) {
        HttpSession session = request.getSession();
        String urlType = (String) request.getSession().getAttribute("attachment");
        request.getSession().removeAttribute("attachment");
        //租户类型
        model.addAttribute("urlType", urlType);
        try {
            boolean auth = authenticateService.auth(session, saasAdmin);
            if (!auth) {
                //授权失败
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                PrintWriter out = null;
                try {
                    out = response.getWriter();
//                    out.print("<script>alert('登录地址有误-用户授权失败！');</script>");
                    response.sendRedirect("/esb/tenantAutoFail");
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    IOUtils.closeQuietly(out);
                }
            } else {
                remoteShellService.start();//启动
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        model.addAttribute("contentPage", "/common/login");
        return "pageView";
    }


    /**
     * 租户登录页面
     *
     * @param model
     * @param tenantName
     * @param request
     * @return
     */
    @RequestMapping("{tenantName}/loginPage")
    public String tenantLogin(Model model,
                              @PathVariable(name = "tenantName") String tenantName,
                              HttpServletRequest request, HttpServletResponse response) throws IOException {
        HttpSession session = request.getSession();
        boolean auth = false;
        try {
            auth = authenticateService.auth(session, tenantName);
            System.out.println("auth:   " + auth);
            if (!auth) {
                //授权失败，切换回管理平台数据库
                response.setCharacterEncoding("UTF-8");
                response.setHeader("Content-type", "text/html;charset=UTF-8");
                PrintWriter out = null;
                try {
                    out = response.getWriter();
//                    out.print("<script>alert('请求地址不存在！');</script>");
                    response.sendRedirect("/esb/tenantAutoFail");
                    out.flush();
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    IOUtils.closeQuietly(out);
                }
            } else {
                remoteShellService.start();//启动远程连接
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        model.addAttribute("contentPage", "/common/login");
        return "pageView";

    }

    /*
首页页面
 */
    @RequestMapping("indexPage")
    public String index(HttpServletRequest request, Model model) {
        HttpSession session = request.getSession();
        SystemUser user = (SystemUser) session.getAttribute("userInfo");

        if (session.getAttribute(ContextAttributes.TENANT_SESSION)!=null){
            TenantSession tenantSession = (TenantSession) session.getAttribute(ContextAttributes.TENANT_SESSION);
            model.addAttribute("tenant", tenantSession.getTenant());
        }
;
        model.addAttribute("userName", user.getUserName());
        //获取菜单
        String menu = "[{id: 1, text: '任务管理',icon:'${staticRoot}/images/index/menu2_icon.png'},\n" +
                "        {id: 11, pid: 1, text: '任务跟踪', url: '${contextRoot}/datacollect/trackJob',targetType:'1'},\n" +
                "        {id: 12, pid: 1, text: '任务补采', url: '${contextRoot}/datacollect/repeatDatacollect'},\n" +
                "        {id: 13, pid: 1, text: '任务配置', url: '${contextRoot}/datacollect/configJob'},\n" +
                "        {id: 2, text: '标准管理',icon:'${staticRoot}/images/index/menu3_icon.png'},\n" +
                "        {id: 21, pid: 2, text: '集成标准', url: '${contextRoot}/integration/initial/standard'},\n" +
                "        {id: 22, pid: 2, text: '应用标准', url: '${contextRoot}/integration/initial/application'},\n" +
                "        {id: 23, pid: 2, text: '适配方案', url: '${contextRoot}/adapterPlan/initial'},\n" +
                "        {id: 3, text: '资源管理',icon:'${staticRoot}/images/index/menu4_icon.png'},\n" +
                "        {id: 31, pid: 3, text: '资源注册', url: '${contextRoot}/resource/resource/initial'},\n" +
                "        {id: 32, pid: 3, text: '资源浏览', url: '${contextRoot}/resource/resourcePage'},\n" +
                "        {id: 34, pid: 3, text: '资源分类', url: '${contextRoot}/resource/rsCategory/initial'},\n" +
                "        {id: 35, pid: 3, text: '业务资源', url: '${contextRoot}/resourceRest/initial'},\n" +
                "        {id: 4, text: '维度管理',icon:'${staticRoot}/images/index/menu5_icon.png'},\n" +
                "        {id: 41, pid: 4, text: '维度配置', url: '${contextRoot}/dimension/dimension'},\n" +
                "        {id: 42, pid: 4, text: '维度类别配置', url: '${contextRoot}/dimension/dimensioncatetory'},\n" +
                "        {id: 9, text: '系统配置',icon:'${staticRoot}/images/index/menu6_icon.png'},\n" +
                "        {id: 91, pid: 9, text: '机构配置', url: '${contextRoot}/org/initial'},\n" +
                "        {id: 92, pid: 9, text: '数据源配置', url: '${contextRoot}/datasource/configSources'},\n" +
                "        {id: 93, pid: 9, text: '菜单配置', url: '${contextRoot}/menu/initial'},\n" +
                "        {id: 100, pid: 9, text: '菜单按钮配置', url: '${contextRoot}/menu/menuAction/initial'},\n" +
                "        {id: 94, pid: 9, text: '用户管理', url: '${contextRoot}/user/initial'},\n" +
                "        {id: 95, pid: 9, text: '角色管理', url: '${contextRoot}/role/initial'},\n" +
                "        {id: 96, pid: 9, text: '权限管理', url: '${contextRoot}/authority/initial'},\n" +
                "        {id: 97, pid: 9, text: '字典管理', url: '${contextRoot}/dict/initial' },\n" +
                "        {id: 98, pid: 9, text: '系统参数', url: '${contextRoot}/param/initial'},\n" +
                "        {id: 99, pid: 9, text: '<spring:message code=\"title.app.manage\"/>', url: '${contextRoot}/app/initial'}]";
        model.addAttribute("menu", menu);

        model.addAttribute("contentPage", "/common/index");
        return "pageView";
    }


    /**
     * oauth2 自动登录后首页
     *
     * @param tenantName 租户名称
     * @param request
     * @param model
     * @return
     */
    @RequestMapping("{tenantName}/oauth2/index")
    public String tenantIndex(
            @PathVariable(name = "tenantName") String tenantName,
            HttpServletRequest request, Model model) {

        HttpSession session = request.getSession();
        boolean auth = false;
        String loginName = request.getParameter(ContextAttributes.LOGIN_NAME);

        SystemUser userInfo = new SystemUser();
        userInfo.setLoginCode(loginName);
        userInfo.setUserName("管理员");
        session.setAttribute("userInfo", userInfo);
        try {
            auth = authenticateService.auth(session, tenantName);
            if (!auth) {
                model.addAttribute("contentPage", "/common/tokenValidFail");
                return "pageView";
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        model.addAttribute("userName", loginName);
        model.addAttribute("tenant", tenantName);
        //获取菜单
        String menu = "[{id: 1, text: '任务管理',icon:'${staticRoot}/images/index/menu2_icon.png'},\n" +
                "        {id: 11, pid: 1, text: '任务跟踪', url: '${contextRoot}/datacollect/trackJob',targetType:'1'},\n" +
                "        {id: 12, pid: 1, text: '任务补采', url: '${contextRoot}/datacollect/repeatDatacollect'},\n" +
                "        {id: 13, pid: 1, text: '任务配置', url: '${contextRoot}/datacollect/configJob'},\n" +
                "        {id: 2, text: '标准管理',icon:'${staticRoot}/images/index/menu3_icon.png'},\n" +
                "        {id: 21, pid: 2, text: '集成标准', url: '${contextRoot}/integration/initial/standard'},\n" +
                "        {id: 22, pid: 2, text: '应用标准', url: '${contextRoot}/integration/initial/application'},\n" +
                "        {id: 23, pid: 2, text: '适配方案', url: '${contextRoot}/adapterPlan/initial'},\n" +
                "        {id: 3, text: '资源管理',icon:'${staticRoot}/images/index/menu4_icon.png'},\n" +
                "        {id: 31, pid: 3, text: '资源注册', url: '${contextRoot}/resource/resource/initial'},\n" +
                "        {id: 32, pid: 3, text: '资源浏览', url: '${contextRoot}/resource/resourcePage'},\n" +
                "        {id: 34, pid: 3, text: '资源分类', url: '${contextRoot}/resource/rsCategory/initial'},\n" +
                "        {id: 35, pid: 3, text: '业务资源', url: '${contextRoot}/resourceRest/initial'},\n" +
                "        {id: 4, text: '维度管理',icon:'${staticRoot}/images/index/menu5_icon.png'},\n" +
                "        {id: 41, pid: 4, text: '维度配置', url: '${contextRoot}/dimension/dimension'},\n" +
                "        {id: 42, pid: 4, text: '维度类别配置', url: '${contextRoot}/dimension/dimensioncatetory'},\n" +
                "        {id: 9, text: '系统配置',icon:'${staticRoot}/images/index/menu6_icon.png'},\n" +
                "        {id: 91, pid: 9, text: '机构配置', url: '${contextRoot}/org/initial'},\n" +
                "        {id: 92, pid: 9, text: '数据源配置', url: '${contextRoot}/datasource/configSources'},\n" +
                "        {id: 93, pid: 9, text: '菜单配置', url: '${contextRoot}/menu/initial'},\n" +
                "        {id: 100, pid: 9, text: '菜单按钮配置', url: '${contextRoot}/menu/menuAction/initial'},\n" +
                "        {id: 94, pid: 9, text: '用户管理', url: '${contextRoot}/user/initial'},\n" +
                "        {id: 95, pid: 9, text: '角色管理', url: '${contextRoot}/role/initial'},\n" +
                "        {id: 96, pid: 9, text: '权限管理', url: '${contextRoot}/authority/initial'},\n" +
                "        {id: 97, pid: 9, text: '字典管理', url: '${contextRoot}/dict/initial' },\n" +
                "        {id: 98, pid: 9, text: '系统参数', url: '${contextRoot}/param/initial'},\n" +
                "        {id: 99, pid: 9, text: '<spring:message code=\"title.app.manage\"/>', url: '${contextRoot}/app/initial'}]";
        model.addAttribute("menu", menu);


        model.addAttribute("contentPage", "/common/index");
        //从此处登入不显示logo（标识showLogo==false）
        model.addAttribute("showLogo", "false");

        return "pageView";
    }

    /**
     * oauth2 自动登陆中间页
     *
     * @param model
     * @param tenantName
     * @return
     */
    @RequestMapping(value = "{tenantName}/oauth2/signin")
    public String signin(Model model,
                         @PathVariable(name = "tenantName") String tenantName) {
        model.addAttribute("tenantName", tenantName);
        model.addAttribute("contentPage", "common/signin");
        model.addAttribute("successFlg", true);
        return "pageView";
    }

    /*
      *  oauth2 自动登录
      */
    @RequestMapping(value = "oauth2/autoLogin", method = RequestMethod.POST)
    @ResponseBody
    public Envelop autoLogin(Model model,
                             HttpServletRequest request,
                             @ApiParam(name = "token")
                             @RequestParam String token) throws Exception {
        try {
            HttpSession session = request.getSession();
            Map<String, String> params = new HashMap<>();
            params.put("clientId", clientId);
            params.put("accessToken", token);

            HTTPResponse response = HttpClientKit.post(oauth2authUrl + "/oauth/validToken", params);
            if (response.getStatusCode() != 200) {
                System.out.println("验证 token 请求失败，token："+token);
                return failed("验证 token 请求失败！");
            }

            Map map = objectMapper.readValue(response.getBody(), Map.class);
            if ((Boolean) map.get("successFlg")) {
                AccessToken accessToken = objectMapper.readValue(objectMapper.writeValueAsString(map.get("data")), AccessToken.class);
                String loginName = accessToken.getUser();
                session.setAttribute("ehrUser",loginName);
                //验证通过。赋值session中的用户信息
                HTTPResponse userResponse = HttpClientKit.get(adminUrl + "/users/" + loginName, params);
                Envelop result =  this.objectMapper.readValue(userResponse.getBody(), Envelop.class);
                Collection<GrantedAuthority> gas = new ArrayList<>();
                if (result.isSuccessFlg()) {
                    String ex = this.objectMapper.writeValueAsString(result.getObj());
                    Map userMap = objectMapper.readValue(ex, Map.class);
                    //TODO 设置当前登录用户
                    String userId = userMap.get("id").toString();
                    List<AppFeatureModel> features = getUserFeatures(userId);
                    if (features != null) {
                        for (int i = 0; i < features.size(); i++) {
                            String url = features.get(i).getUrl();
                            if (!StringUtils.isEmpty(url))
                                gas.add(new SimpleGrantedAuthority(url));
                        }
                    }
                } else {
                    return failed(result.getErrorMsg());
                }


                //生成认证token
                Authentication AuthenticationToken = new UsernamePasswordAuthenticationToken(loginName, "", gas);
                //将信息存放到SecurityContext
                SecurityContextHolder.getContext().setAuthentication(AuthenticationToken);

                return success(accessToken);
            } else {
                String msg = String.valueOf(map.get("message"));
                return failed(msg);
            }
        } catch (Exception e) {
            e.printStackTrace();
            return failed(e.getMessage());
        }
    }


    /*
    系统主页
     */
    @RequestMapping("homePage")
    public String home(Model model) {
        model.addAttribute("contentPage", "/common/home");
        return "partView";
    }

    private List<AppFeatureModel> getUserFeatures(String userId) throws Exception {
        Map<String, String> params = new HashMap<>();
        params.put("user_id", userId);
        HTTPResponse resultStr = HttpClientKit.get(adminUrl + "/roles/user/features", params);
        EnvelopExt<AppFeatureModel> envelop =
                (EnvelopExt<AppFeatureModel>) objectMapper.readValue(resultStr.getBody(), new TypeReference<EnvelopExt<AppFeatureModel>>() {
                });
        if (envelop.isSuccessFlg()) {
            return envelop.getDetailModelList();
        }
        throw new Exception(resultStr.getBody());
    }

    @Autowired
    public void setRemoteShellService(RemoteShellService remoteShellService) {
        this.remoteShellService = remoteShellService;
    }
}
