package com.house365.web.controller;

import com.google.common.base.Strings;
import com.house365.beans.entity.DepartmentEntity;
import com.house365.beans.entity.RequestLoginEntity;
import com.house365.beans.entity.UserEntity;
import com.house365.rest.context.ServiceConstant;
import com.house365.web.cached.RedisUtilsInterface;
import com.house365.web.system.controller.BaseController;
import com.house365.web.util.*;
import com.house365.ws.beans.request.UserListRequest;
import com.house365.ws.beans.request.UserRequest;
import com.house365.ws.beans.response.DepartmentResponse;
import com.house365.ws.beans.response.UserListResponse;
import com.house365.ws.beans.response.UserResponse;
import com.house365.ws.interfaces.server.IDepartment;
import com.house365.ws.interfaces.server.IUser;
import org.apache.commons.lang.ArrayUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.subject.Subject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.house365.web.util.SessionConstants.THREAD_USERID_KEY;

/**
 * 登录、登出、首页等
 */
@Controller
@RequestMapping("/")
public class LoginController extends BaseController {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private IDepartment department;

    @Autowired
    private IUser user;

    @Autowired
    private RedisUtilsInterface redisUtil;

    /**
     * home page
     *
     * @param response
     * @param request
     * @return
     */
    @RequestMapping(value = {"login"}, method = {RequestMethod.GET})
    public String login(Model model, HttpServletResponse response, HttpServletRequest request) {
        Cookie[] cookies = request.getCookies();
        // 用户第一次打开登录页，没有 cookie 信息，此时不从 cookie 中读取登录信息
        if (ArrayUtils.isEmpty(cookies)) {
            return getAutoUrl();
        }
        String[] cooks = null;
        String cookieName = null;
        String account = null;
        String password = null;
        for (Cookie coo : cookies) {
            cookieName = coo.getName();
            if ("_ap".equals(cookieName)) {
                String aa = coo.getValue();
                cooks = aa.split("%%");
                if (cooks.length == 2) {
                    account = cooks[0];
                    password = cooks[1];
                }
            }
        }
        // 部署环境标识，[test] or [production]
        String env = MemoryPropertyPlaceholderConfigurer.getContextProperty("system.env");
        model.addAttribute("account2", account);
        model.addAttribute("password2", password);
        model.addAttribute("env", env);

        return "/index/pages/login";
    }

    /**
     * 根据 loginName 获取帐户信息
     *
     * @param loginName 登录名
     * @return 帐户 entity,获取不到返回 null
     */
    private UserEntity getUser(String loginName, String password) {
        Map<String, Object> searchMap = new HashMap<>();
        UserListRequest userListRequest = new UserListRequest();
        searchMap.put("EQ_name", loginName);
        searchMap.put("EQ_password", password);

        userListRequest.setSearchParams(searchMap);
        UserListResponse userListResponse = user.getUserList(userListRequest);
        UserEntity accountEntity = null;
        if (userListResponse != null && !userListResponse.getObjectList().isEmpty()) {
            accountEntity = userListResponse.getObjectList().get(0);
        }

        return accountEntity;
    }

    /**
     * 用户登录成功后，将相关信息保存到 session 等作用域
     *
     * @param userEntity 用户账户
     */
    private void setUserInfoToScope(HttpServletRequest request, UserEntity userEntity) {
        DepartmentResponse departmentResponse = department.getDepartmentById(userEntity.getDeptId());
        DepartmentEntity dept = departmentResponse.getEntity();
        request.getSession().setAttribute(SessionConstants.SESSION_REAL_DEPT_KEY, dept);
        Integer realDept = PathUtil.extractDept(dept.getUrlPath());
        if (!userEntity.getDeptId().equals(realDept)) {
            dept = department.getDepartmentById(realDept).getEntity();
        }
        request.getSession().setAttribute(SessionConstants.SESSION_ORIGIN_DEPT_KEY, dept);
        request.getSession().setAttribute(SessionConstants.SESSION_CURRNET_DEPT_KEY, dept);

        request.getSession().setAttribute(SessionConstants.THREAD_USER_KEY, userEntity);
        request.getSession().setAttribute(SessionConstants.THREAD_USERID_KEY, userEntity.getId());
        request.getSession().setAttribute(SessionConstants.THREAD_USERNAME_KEY, userEntity.getName());
        request.getSession().setAttribute(SessionConstants.SESSION_CITY_KEY, dept.getDescripition());
    }

    /**
     * 执行登录操作<br>
     * 用户登录成功后，将相关信息保存到 session 等作用域
     *
     * @return 结果视图
     */
    @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
    @ResponseBody
    public String doLogin(Model model, HttpServletRequest request, HttpServletResponse response) {

        try {
            String account = request.getParameter("account").trim();
            String password = request.getParameter("password").trim();
            String autoLogin = request.getParameter("autoLogin");

            UsernamePasswordToken token = new UsernamePasswordToken(account, password);
            token.setRememberMe(true);
            Subject currentUser = SecurityUtils.getSubject();
            currentUser.login(token);
            if (currentUser.isAuthenticated()) {
                UserEntity accountEntity = getUser(account, password);

                //限制登陆
                //获取Ip地址
                UserEntity loginentity = user.getLimitLoginById(account);
                String address = "";
                String ip = "";
                if ("1".equals(loginentity.getLimitLogin())) {
                    ip = RequestFromUtil.getIpAddr(request);
                    LOGGER.error("**********请求IP地址1:***********" + ip);
                    if (ip.contains(",")) {
                        ip = ip.split(",")[0];
                    }
                    LOGGER.error("**********请求IP地址2:***********" + ip);
                    //获取地理位置
                    address = AddressUtils.readJsonFromUrl("http://api.map.baidu.com/location/ip?ak=F454f8a5efe5e577997931cc01de3974&ip=" + ip);
                }

//                String userIp = RemoteIpUtils.getIpAddr(request);

                String requestHeader = request.getHeader("user-agent");
//                if(!RequestFromUtil.isMobileDevice(requestHeader)){//PC端请求
//                    LOGGER.error("*******************************移动端请求:*************************");
                LOGGER.error("*******************************PC端请求:***************************");

                if ("1".equals(loginentity.getLimitLogin()) && (!"218.94.115.128".equals(ip) && !"218.94.115.129".equals(ip) && !"218.94.115.130".equals(ip) && !"218.94.115.131".equals(ip)
                        && !"218.94.115.132".equals(ip) && !"218.94.115.133".equals(ip) && !"218.94.115.134".equals(ip)) && !"218.94.115.135".equals(ip)) {
//                        redisUtil.addKeyValExpire(account+ "_" +ip, );
                    //先确定是否已经登陆授权并未超时失效
                    RequestLoginEntity requestlogin = new RequestLoginEntity();
                    //需授权的账号在外部登陆PC端,记录登陆信息
                    Date dateStr = new Date();
                    requestlogin.setName(account);
                    requestlogin.setLoginIp(ip);
                    requestlogin.setRealName(accountEntity.getRealName());
                    requestlogin.setLoginTime(dateStr);
                    requestlogin.setLoginCity(address);
                    requestlogin.setUserId(accountEntity.getId());
                    List<RequestLoginEntity> requestList = user.getRequestLoginInfo(requestlogin);
                    if (requestList != null && requestList.size() > 0) {
                        Date requestTime = requestList.get(0).getLoginTime();
                        Date authorizationTime = requestList.get(0).getAuthorizationTime();
                        String status = requestList.get(0).getStatus();
                        long min1 = AddressUtils.getDatePoor(dateStr, requestTime);
                        //请求超过10分钟未授权重新请求再授权
                        if ("0".equals(status)) {
                            if (min1 > 10) {
                                user.addRequestLoginInfo(requestlogin);
                                return "limit_error1";
                            } else {
                                user.addRequestLoginInfo(requestlogin);
                                return "limit_error1";
                            }
                        }
                        //已经授权但并未超过3分钟鉴权通过登陆
                        if ("1".equals(status)) {
                            if (authorizationTime != null) {
                                long min2 = AddressUtils.getDatePoor(dateStr, authorizationTime);
                                if (min2 > 3) {
                                    user.addRequestLoginInfo(requestlogin);
                                    return "limit_error2";
                                }
                            } else {
                                user.addRequestLoginInfo(requestlogin);
                                return "limit_error2";
                            }
                        }
                        //已失效
                        if ("2".equals(status)) {
                            if (authorizationTime != null) {
                                long min2 = AddressUtils.getDatePoor(dateStr, authorizationTime);
                                if (min1 > 10 || min2 > 3) {
                                    user.addRequestLoginInfo(requestlogin);
                                    return "limit_error3";
                                }
                            } else {
                                user.addRequestLoginInfo(requestlogin);
                                return "limit_error3";
                            }
                        }
                    } else {
                        user.addRequestLoginInfo(requestlogin);
                        return "limit_error1";
                    }
                }
//                }
                if (!Strings.isNullOrEmpty(autoLogin) && "on".equalsIgnoreCase(autoLogin)) {
                    Cookie cookie = new Cookie("_ap", account + "%%" + password);
                    cookie.setMaxAge(999999999);
                    response.addCookie(cookie);
                }
                UserRequest userRequest = new UserRequest();
                accountEntity.setPreLoginTime(accountEntity.getLastLoginTime());
                accountEntity.setLastLoginTime(new Date());
                userRequest.setEntity(accountEntity);
                user.updateUser(userRequest);
                setUserInfoToScope(request, accountEntity);
                return "success";
            } else {
                model.addAttribute("account_error", "用户名不存在");
                return "account_error";
            }

        } catch (Exception e) {
            logger.error(e.getMessage());
            model.addAttribute("errorMessge", e.getMessage());
            return e.getMessage();
        }
    }

    /**
     * 校验登陆
     *
     * @return 结果视图
     */
    @RequestMapping(value = "/oaLogin")
    public String oaLogin(Model model, HttpServletRequest request, HttpServletResponse response) {
        try {
            String account = request.getParameter("userName").trim();
            String password = request.getParameter("userPassword").trim();
            // 20160506 需求，系统只允许通过 OA 登录，oa_login 为 OA
            String oaLoginFlag = request.getParameter("oa_login");

            if (!OA_LOGIN_FLAG_VALUE.equalsIgnoreCase(oaLoginFlag)) {
                model.addAttribute("errorMessge", "抱歉，只允许通过OA登录！");
                return "/index/pages/login";
            }

            if (!Strings.isNullOrEmpty(account) && !Strings.isNullOrEmpty(password)) {
                password = MD5Util.MD5(password);
                UsernamePasswordToken token = new UsernamePasswordToken(account, password);
                token.setRememberMe(true);
                Subject currentUser = SecurityUtils.getSubject();
                currentUser.login(token);
                if (currentUser.isAuthenticated()) {
                    UserEntity accountEntity = getUser(account, password);

                    //限制登陆
                    //获取Ip地址
//                    UserEntity loginentity = user.getLimitLoginById(account);
//                    String address = "";
//                    String ip = "";
//                    if ("1".equals(loginentity.getLimitLogin())) {
//                        ip = RequestFromUtil.getIpAddr(request);
//                        LOGGER.error("**********请求IP地址1:***********" + ip);
//                        if (ip.contains(",")) {
//                            ip = ip.split(",")[0];
//                        }
//                        LOGGER.error("**********请求IP地址2:***********" + ip);
//                        //获取地理位置
//                        address = AddressUtils.readJsonFromUrl("http://api.map.baidu.com/location/ip?ak=F454f8a5efe5e577997931cc01de3974&ip=" + ip);
//                    }
                    LOGGER.error("*******************************PC端请求:***************************");

//                    if ("1".equals(loginentity.getLimitLogin()) && (!"218.94.115.128".equals(ip) && !"218.94.115.129".equals(ip) && !"218.94.115.130".equals(ip) && !"218.94.115.131".equals(ip)
//                            && !"218.94.115.132".equals(ip) && !"218.94.115.133".equals(ip) && !"218.94.115.134".equals(ip)) && !"218.94.115.135".equals(ip)) {
//                        //先确定是否已经登陆授权并未超时失效
//                        RequestLoginEntity requestlogin = new RequestLoginEntity();
//                        //需授权的账号在外部登陆PC端,记录登陆信息
//                        Date dateStr = new Date();
//                        requestlogin.setName(account);
//                        requestlogin.setLoginIp(ip);
//                        requestlogin.setRealName(accountEntity.getRealName());
//                        requestlogin.setLoginTime(dateStr);
//                        requestlogin.setLoginCity(address);
//                        requestlogin.setUserId(accountEntity.getId());
//                        List<RequestLoginEntity> requestList = user.getRequestLoginInfo(requestlogin);
//                        if (requestList != null && requestList.size() > 0) {
//                            Date requestTime = requestList.get(0).getLoginTime();
//                            Date authorizationTime = requestList.get(0).getAuthorizationTime();
//                            String status = requestList.get(0).getStatus();
//                            long min1 = AddressUtils.getDatePoor(dateStr, requestTime);
//                            //请求超过10分钟未授权重新请求再授权
//                            if ("0".equals(status)) {
//                                if (min1 > 10) {
//                                    user.addRequestLoginInfo(requestlogin);
//                                    return "limit_error1";
//                                } else {
//                                    user.addRequestLoginInfo(requestlogin);
//                                    return "limit_error1";
//                                }
//                            }
//                            //已经授权但并未超过3分钟鉴权通过登陆
//                            if ("1".equals(status)) {
//                                if (authorizationTime != null) {
//                                    long min2 = AddressUtils.getDatePoor(dateStr, authorizationTime);
//                                    if (min2 > 3) {
//                                        user.addRequestLoginInfo(requestlogin);
//                                        return "limit_error2";
//                                    }
//                                } else {
//                                    user.addRequestLoginInfo(requestlogin);
//                                    return "limit_error2";
//                                }
//                            }
//                            //已失效
//                            if ("2".equals(status)) {
//                                if (authorizationTime != null) {
//                                    long min2 = AddressUtils.getDatePoor(dateStr, authorizationTime);
//                                    if (min1 > 10 || min2 > 3) {
//                                        user.addRequestLoginInfo(requestlogin);
//                                        return "limit_error3";
//                                    }
//                                } else {
//                                    user.addRequestLoginInfo(requestlogin);
//                                    return "limit_error3";
//                                }
//                            }
//                        } else {
//                            user.addRequestLoginInfo(requestlogin);
//                            return "limit_error1";
//                        }
//                    }

                    UserRequest userRequest = new UserRequest();
                    accountEntity.setPreLoginTime(accountEntity.getLastLoginTime());
                    accountEntity.setLastLoginTime(new Date());
                    userRequest.setEntity(accountEntity);
                    user.updateUser(userRequest);
                    setUserInfoToScope(request, accountEntity);
                    System.out.println("即将跳转index页面，userId 为 ： " + account + " password为 " + password);
                    return "redirect:index";
                } else {
                    model.addAttribute("errorMessge", "用户不存在!");
                    return "/index/pages/login";
                }

            } else {
                // 用户名，密码为空时提示
                if (account == null && password == null) {
                    model.addAttribute("errorMessge", "用户或密码为空!");
                    return "/index/pages/login";
                }
                if (account == null) {
                    model.addAttribute("errorMessge", "用户不存在!");
                    return "/index/pages/login";
                }
                if (password == null) {
                    model.addAttribute("errorMessge", "密码不正确!");
                    return "/index/pages/login";
                }
            }
        } catch (Exception e) {
            model.addAttribute("errorMessge", e.getMessage());
            return "/index/pages/login";
        }
        return "/index/pages/login";
    }

    /**
     * 用户退出系统 删除会话中与用户相关的数据
     *
     * @return 页面跳转标识
     */
    @RequestMapping(value = "/logout", method = RequestMethod.GET)
    public String logout(
            Model model, HttpServletRequest request, HttpServletResponse response
    ) {
        UserEntity userEntity = (UserEntity) request.getSession().getAttribute(SessionConstants.THREAD_USER_KEY);
        String ip = RequestFromUtil.getIpAddr(request);
        LOGGER.error("**********请求IP地址1:***********" + ip);
        if (ip.contains(",")) {
            ip = ip.split(",")[0];
        }
        LOGGER.error("**********请求IP地址2:***********" + ip);
        Subject currentUser = SecurityUtils.getSubject();
        currentUser.logout();

        HttpSession session = request.getSession(true);
        // 删除会话中的用户数据 同时注销会话
        session.removeAttribute("session_accout");
        session.removeAttribute("phoneNumberPrompt");
        session.removeAttribute("phoneAuthCode");
        session.removeAttribute("userId");
        session.removeAttribute("userName");
        session.removeAttribute("userPhone");
        session.removeAttribute("cityId");
        session.removeAttribute(ServiceConstant.CITY_CODE);
        session.removeAttribute(ServiceConstant.CITY_NAME);
        session.invalidate();
        //将请求置为已失效
        RequestLoginEntity requestloginentity = new RequestLoginEntity();
        requestloginentity.setUserId(userEntity.getId());
        requestloginentity.setLoginIp(ip);
        user.updateRequestById(requestloginentity);

        // Cookie cookie = new Cookie("_ap", "");
        // cookie.setMaxAge(999999999);
        // response.addCookie(cookie);
        return redirect("/login");
    }

    @RequestMapping(value = "/toEditPasswd", method = {RequestMethod.GET})
    public String editPasswd(Model model, HttpServletRequest request) {
        return "/index/pages/editPasswd";
    }

    /**
     * 修改密码
     *
     * @return 结果视图
     */
    @RequestMapping(value = "/modifyPWD", method = {RequestMethod.GET})
    public String modifyPwd(Model model, HttpServletRequest request) {
        Integer userId = (Integer) request.getSession().getAttribute(THREAD_USERID_KEY);
        String nowPwd = request.getParameter("nowPwd").trim();
        String newPwd = request.getParameter("newPwd").trim();
        String againNewPwd = request.getParameter("againNewPwd").trim();
        if ("".equals(nowPwd) || nowPwd == null) {
            addErrorMessage(model, "原始密码不能为空！");
            return "/index/pages/editPasswd";// 原始密码不能为空
        }
        if ("".equals(newPwd) || newPwd == null) {
            addErrorMessage(model, "新密码不能为空！");
            return "/index/pages/editPasswd";// 新密码不能为空
        }
        if ("".equals(againNewPwd) || againNewPwd == null) {
            addErrorMessage(model, "确认密码不能为空！");
            return "/index/pages/editPasswd";// 确认密码不能为空
        }

        try {
            if (userId != null) {
                UserResponse userResponse = user.getUserById(userId);
                UserEntity userEntity = userResponse.getEntity();
                if (userEntity != null && (!"".equals(nowPwd) && nowPwd != null)) {
                    // md5加密
                    String nowPwdMD5 = MD5Util.MD5(nowPwd);
                    if (nowPwdMD5.equalsIgnoreCase(userEntity.getPassword())) {
                        if (newPwd.equalsIgnoreCase(againNewPwd)) {
                            UserRequest userRequest = new UserRequest();
                            userEntity.setPassword(MD5Util.MD5(newPwd));
                            userRequest.setEntity(userEntity);
                            UserResponse userResponse1 = user.updateUser(userRequest);
                            if ("10000".equals(userResponse1.getResultCode())) {
                                addSuccessMessage(model, "修改密码成功！");
                                model.addAttribute("successFlag", true);
                                return "/index/pages/editPasswd";
                            }
                        } else {
                            addErrorMessage(model, "输入的两次密码不一致！");
                            return "/index/pages/editPasswd";
                        }
                    } else {
                        addErrorMessage(model, "原始密码错误！");
                        return "/index/pages/editPasswd";
                    }

                } else {
                    // 账号异常
                    return "/";
                }
            }
        } catch (Exception ex) {
            addErrorMessage(model, ex.getMessage());
            return "/";
        }
        return "/";
    }


    // 20160506 需求，系统只允许通过 OA 登录，oa_login 为 OA 登录标识，值为：md5('365quickdial')
    private static final String OA_LOGIN_FLAG_VALUE = MD5Util.MD5("365quickdial");

    protected static final Logger LOGGER = LoggerFactory.getLogger(LoginController.class);


}
