package com.zcloud.controller.system;

import com.zcloud.controller.base.BaseController;
import com.zcloud.entity.PageData;
import com.zcloud.entity.system.User;
import com.zcloud.logs.LogAnno;
import com.zcloud.service.corp.CorpInfoService;
import com.zcloud.service.offduty.OffDutyService;
import com.zcloud.service.system.*;
import com.zcloud.util.*;
import net.sf.json.JSONObject;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;

/**
 * 说明：登录处理类 作者：luoxiaobao 官网：www.qdkjchina.com
 */
@Controller
@RequestMapping("/admin")
public class LoginController extends BaseController {

    @Autowired
    private UsersService usersService;
    @Autowired
    private RoleService roleService;
    @Autowired
    private FHlogService FHLOG;
    @Autowired
    private DepartmentService departmentService;
    @Autowired
    private CorpInfoService corpinfoService;
    @Autowired
    private OffDutyService offdutyService;
    @Autowired
    private SupervisionDepartmentService supervisionDepartmentService;

    @Resource
    private RedisUtil redisUtil;

    /**
     * 请求登录验证用户接口
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/check", produces = "application/json;charset=UTF-8")
    @ResponseBody
    @LogAnno(menuType = "首页", menuServer = "首页", instructionsOperate = "登录", instructionsType = "请求登录验证用户接口")
    public Object check() throws Exception {
        // 获取IP
        HttpServletRequest request = this.getRequest();
        String ip = "";
        if (request.getHeader("x-forwarded-for") == null) {
            ip = request.getRemoteAddr();
        } else {
            ip = request.getHeader("x-forwarded-for");
        }
        Boolean isLogin = true; // 当subject.login
        // 验证不通过时，用于跳过后续操作（有时会出现subject.login验证不通过，但是subject.isAuthenticated为true的情况）
        Map<String, Object> map = new HashMap<String, Object>();
//		if(!BasicInfoUtil.checkValid()) {
//			String errInfo = "invalid";
//			map.put("result", errInfo);
//			return map;
//		}
        PageData pd = new PageData();
        pd = this.getPageData();
        String source = pd.getString("SOURCE");
        String errInfo = "success";
        String loginData = pd.getString("KEYDATA");
        if (loginData.indexOf("zcloudchina") == -1) {
            loginData = RSAUtils.decryptDataOnJava(loginData, RSAUtils.getPrivateKey());
        }
        String KEYDATA[] = loginData.replaceAll("zcloudchina", "").split(",zy,");

        if (null != KEYDATA && KEYDATA.length == 2) {
            String USERNAME = KEYDATA[0]; // 登录过来的用户名
            String PASSWORD = KEYDATA[1]; // 登录过来的密码
            UsernamePasswordToken token;
            if (null != pd.get("isLogin")) {
                token = new UsernamePasswordToken(USERNAME, PASSWORD);
            } else {
                token = new UsernamePasswordToken(USERNAME, new SimpleHash("SHA-1", USERNAME, PASSWORD).toString());
            }
            Subject subject = SecurityUtils.getSubject();
            try {
                subject.login(token); // 这一步在调用login(token)方法时,它会走到MyRealm.doGetAuthenticationInfo()方法中
            } catch (UnknownAccountException uae) {
                errInfo = "usererror";
                isLogin = false;
            } catch (IncorrectCredentialsException ice) {
                errInfo = "usererror";
                isLogin = false;
            } catch (LockedAccountException lae) {
                errInfo = "usererror";
                isLogin = false;
            } catch (ExcessiveAttemptsException eae) {
                errInfo = "usererror";
                isLogin = false;
            } catch (DisabledAccountException sae) {
                errInfo = "usererror";
                isLogin = false;
            } catch (AuthenticationException ae) {
                errInfo = "usererror";
                isLogin = false;
            }
            System.out.println(PASSWORD);
            try {
                if (subject.isAuthenticated() && isLogin) { // 验证是否登录成功
                    removeSession(USERNAME);
                    Session session = Jurisdiction.getSession();
                    pd.put("USERNAME", USERNAME);
                    pd = usersService.findByUsername(pd);
                    PageData cpd = corpinfoService.findById(pd);
//					if (pd != null && pd.get("RIGHTS") != null && Tools.notEmpty(pd.get("RIGHTS").toString())
//							&& "788664966448".equals(pd.get("RIGHTS").toString())) {
                    map.put("USERNAME", USERNAME);
                    map.put("USER_ID", pd.getString("USER_ID"));
                    map.put("NAME", pd.getString("NAME"));
                    map.put("ISMAIN", pd.getString("ISMAIN"));
                    map.put("IS_SAFETY", pd.get("IS_SAFETY"));
                    map.put("ISHEAD", pd.getString("ISHEAD"));
                    map.put("ISLEADER", pd.getString("ISLEADER"));
                    map.put("DEPARTMENT_ID", pd.getString("DEPARTMENT_ID"));
                    map.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
                    map.put("CORP_NAME", cpd.getString("CORP_NAME"));
                    map.put("PROVINCE", cpd.getString("PROVINCE"));
                    map.put("PLS_ID", pd.getOrDefault("PLS_ID", ""));
                    map.put("CARDNO", pd.getOrDefault("CARDNO", ""));
                    map.put("POST_URL", cpd.getOrDefault("POST_URL", ""));
//	        	PageData dpd = new PageData();
//	        	dpd.put("DEPARTMENT_ID", pd.getString("DEPARTMENT_ID"));
//	        	dpd=departmentService.findById(dpd);
//	        	map.put("DEPARTMENT_NAME", dpd.getString("NAME"));
//	        	map.put("PARENT_NAME", dpd.getString("PARENT_NAME"));
                    PageData rpd = roleService.findById(pd);
                    map.put("ROLEID", rpd.getString("ROLE_ID"));
                    map.put("ROLE_NAME", rpd.getString("ROLE_NAME"));
                    map.put("USERBZ", pd.getString("BZ"));
                    PageData dpd = new PageData();
                    dpd.put("DEPARTMENT_ID", pd.getString("DEPARTMENT_ID"));
                    dpd = departmentService.findById(dpd);
                    if ("1".equals(dpd.getString("FOREIGNPERSONNEL"))) {
                        return ReturnMap.error("外来部门人员无法登录本系统");
                    }
                    map.put("DEPARTMENT_NAME", dpd.getString("NAME"));
                    map.put("DEPARTMENT_LEVEL", dpd.getString("LEVEL"));
                    map.put("ISSUPERVISE", dpd.getString("ISSUPERVISE"));
                    User user = new User();
                    user.setUSER_ID(pd.getString("USER_ID"));
                    user.setUSERNAME(pd.getString("USERNAME"));
                    user.setPASSWORD(pd.getString("PASSWORD"));
                    user.setNAME(pd.getString("NAME"));
                    user.setROLE_ID(pd.getString("ROLE_ID"));
                    user.setLAST_LOGIN(pd.getString("LAST_LOGIN"));
                    user.setIP(pd.getString("IP"));
                    user.setSTATUS(pd.getString("STATUS"));
                    user.setSuperviseDepartId(this.superviseDepart(dpd)); //监管下部门ID
                    if (Tools.notEmpty(pd.getString("WORKSTATUS")) && "2".equals(pd.getString("WORKSTATUS"))) {// 查看用户是否处于周期性休班中
                        // 休班（周期性）
                        map.put("ISREST", "1");
                    } else {
                        // 查看用户是否在休假中
                        PageData isRest = this.getPageData();
                        isRest.put("ISREST", "1");
                        isRest.put("USER_ID", pd.getString("USER_ID"));
                        isRest.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
                        List<PageData> restList = offdutyService.listAll(isRest);
                        if (restList != null && restList.size() > 0) {
                            // 休假中
                            map.put("ISREST", "1");
                        } else {
                            // 正常工作
                            map.put("ISREST", "0");
                        }
                    }
                    map.put("deptList", departmentService.listAll(cpd));
                    map.put("userList", usersService.listAllUser(cpd));
                    map.put("CORP_TRAINTYPE", Tools.isEmpty(cpd.getString("TRAINTYPE")) ? "" : cpd.getString("TRAINTYPE"));// 用户所属企业的培训行业类型到
                    session.setAttribute(Const.SESSION_USER, user); // 把当前用户放入session
                    session.setAttribute("PERSONNEL_POSITION", cpd.getString("PERSONNEL_POSITION")); // 把当前企业是否有定位服务放session
                    session.setAttribute(Const.DEPARTMENT_ID, pd.getString("DEPARTMENT_ID")); // 把当前用户放入session
                    session.setAttribute(Const.ISSUPERVISE, dpd.getString("ISSUPERVISE")); // 把当前用户放入session
                    session.setAttribute(Const.VIPLEVEL, cpd.getString("VIPLEVEL")); // 把当前用户放入session
                    session.setAttribute(Const.CORPINFO_ID, pd.getString("CORPINFO_ID")); // 把当前用户企业放入session
                    session.setAttribute(Const.POST_ID, pd.getString("POST_ID") == null ? "" : pd.getString("POST_ID")); // 把当前用户岗位放入session
                    session.setAttribute(Const.USER_ID, pd.getString("USER_ID")); // 把当前用户企业放入session
                    session.setAttribute(Const.SESSION_USERNAME, USERNAME); // 放入用户名到session
                    session.setAttribute(Const.SESSION_U_NAME, user.getNAME()); // 放入用户姓名到session
                    session.setAttribute(Const.IS_MAIN, pd.get("ISMAIN")); // 是否主账号
                    session.setAttribute(Const.CORP_TRAINTYPE, Tools.isEmpty(cpd.getString("TRAINTYPE")) ? "" : cpd.getString("TRAINTYPE")); // 放入当前用户所属企业的培训行业类型到session
                    // 判断地址是否存活——开始
                    map.put("webSiteStatus", redisUtil.hget(Const.INTEGRATED_WHB_WEBSITE_SURVIVAL_CHECK_KEY, pd.getString("CORPINFO_ID")));
                    // 记录日志
                    PageData log = new PageData();
                    log.put("USERNAME", USERNAME);
                    log.put("CONTENT", "成功登录系统");
                    log.put("FHLOG_ID", UuidUtil.get32UUID());
                    log.put("IP", ip);
                    log.put("CZTIME", DateUtil.date2Str(new Date()));
                    log.put("SOURCE", source);
                    log.put("USER_ID", pd.getString("USER_ID"));
                    log.put("CORPINFO_ID", pd.getString("CORPINFO_ID"));
                    log.put("TYPE", "1");
                    log.put("NAME", pd.getString("NAME"));
                    log.put("DEPARTMENT", dpd.getString("NAME"));
                    log.put("DEPARTMENT_ID", dpd.getString("DEPARTMENT_ID"));
                    FHLOG.save(log);

                } else {
                    token.clear();
                    errInfo = "usererror";
                }
            } catch (Exception e) {
                e.printStackTrace();
                map.put("msg", "用户名或密码有误");
                return map;
            }
            if (!"success".equals(errInfo)) FHLOG.save(USERNAME, "尝试登录系统失败,用户名密码错误,无权限", ip);

        } else {
            errInfo = "error"; // 缺少参数
        }
        map.put("result", errInfo);
        if ("usererror".equals(errInfo)) {
            map.put("msg", "用户名或密码有误");
        } else if ("error".equals(errInfo)) {
            map.put("msg", "缺少参数");
        }
        return map;
    }

    /**
     * 获取用户监管部门id
     * 等级(0--公司领导，1部门领导，3普通员工)
     *
     * @param userPd 监管部门
     */
    private String superviseDepart(PageData dpd) throws Exception {
        String userSuperviseDepart = "";

        if ("1".equals(dpd.getString("ISSUPERVISE"))) { //还要监管自己部门，如果没有监管自己，要增加上
            dpd.put("SUP_DEPARTMENT_ID", dpd.get("DEPARTMENT_ID"));
            List<PageData> depts = supervisionDepartmentService.listAll(dpd);
            Set<String> supDeptIdSet = new HashSet<String>();
            for (int i = 0; i < depts.size(); i++) {
                supDeptIdSet.add("'" + depts.get(i).getString("DEPARTMENT_ID") + "',");
            }

            userSuperviseDepart = supDeptIdSet.toString();

        }
        return userSuperviseDepart;
    }

    /**
     * 系统用户注册接口
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/register", produces = "application/json;charset=UTF-8")
    @ResponseBody
    public Object register(@RequestParam("callback") String callback) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();
        PageData pd = new PageData();
        pd = this.getPageData();
        String result = "00";
        if (Tools.checkKey("USERNAME", pd.getString("FKEY"))) { // 检验请求key值是否合法
            pd.put("USER_ID", this.get32UUID()); // ID 主键
            pd.put("ROLE_ID", "fhadminzhuche"); // 角色ID fhadminzhuche 为注册用户
            pd.put("NUMBER", ""); // 编号
            pd.put("PHONE", ""); // 手机号
            pd.put("BZ", "注册用户"); // 备注
            pd.put("LAST_LOGIN", ""); // 最后登录时间
            pd.put("IP", ""); // IP
            pd.put("STATUS", "0"); // 状态
            pd.put("SKIN", "pcoded-navbar navbar-image-3,navbar pcoded-header navbar-expand-lg navbar-light header-dark,"); // 用户默认皮肤
            pd.put("EMAIL", "");
            pd.put("ROLE_IDS", "");
            pd.put("PASSWORD", new SimpleHash("SHA-1", pd.getString("USERNAME"), pd.getString("PASSWORD")).toString()); // 密码加密
            if (null == usersService.findByUsername(pd)) { // 判断用户名是否存在
                usersService.saveUser(pd); // 执行保存
                FHLOG.save(pd.getString("USERNAME"), "新注册");
            } else {
                result = "01"; // 用户名已存在
            }
        } else {
            result = "05"; // 不合法的注册
        }
        map.put("result", result);
        JSONObject sresult = JSONObject.fromObject(map);
        ;
        return callback + "(" + sresult.toString() + ")";
    }

    /**
     * 判断是否登录状态
     *
     * @return
     * @throws Exception
     */
    @RequestMapping(value = "/islogin")
    @ResponseBody
    public Object islogin() throws Exception {
        Map<String, String> map = new HashMap<String, String>();
        String errInfo = "success";
        Session session = Jurisdiction.getSession();
        if (null == session.getAttribute(Const.SESSION_USERNAME)) {
            errInfo = "errer";
        }
        map.put("result", errInfo);
        return map;
    }

    /**
     * 清理session
     */
    public void removeSession(String USERNAME) {
        Session session = Jurisdiction.getSession(); // 以下清除session缓存
        session.removeAttribute(Const.SESSION_USER);
        session.removeAttribute(USERNAME + Const.SESSION_ROLE_RIGHTS);
        session.removeAttribute(USERNAME + Const.SESSION_ALLMENU);
        session.removeAttribute(USERNAME + Const.SHIROSET);
        session.removeAttribute(Const.SESSION_USERNAME);
        session.removeAttribute(Const.SESSION_U_NAME);
        session.removeAttribute(Const.SESSION_USERROL);
        session.removeAttribute(Const.SESSION_RNUMBERS);
        session.removeAttribute(Const.SKIN);
    }

    public static void main(String[] args) {
        System.out.println(new SimpleHash("SHA-1", "18700000001", "666666").toString());
    }
}
