package cn.estsh.i3plus.core.apiservice.controller.base;

import cn.estsh.i3plus.core.api.iservice.base.ISystemInitService;
import cn.estsh.i3plus.core.api.iservice.base.ISystemLoginService;
import cn.estsh.i3plus.core.api.iservice.busi.*;
import cn.estsh.i3plus.platform.common.tool.ServletRequestTool;
import cn.estsh.i3plus.platform.common.tool.TimeTool;
import cn.estsh.i3plus.platform.common.util.CommonConstWords;
import cn.estsh.i3plus.pojo.base.enumutil.CommonEnumUtil;
import cn.estsh.i3plus.pojo.base.enumutil.ResourceEnumUtil;
import cn.estsh.i3plus.pojo.platform.bean.SessionUser;
import cn.estsh.i3plus.pojo.platform.bean.SysLogUserLogin;
import cn.estsh.impp.framework.base.controller.CoreBaseController;
import cn.estsh.impp.framework.boot.auth.AuthUtil;
import cn.estsh.impp.framework.boot.exception.ImppBusiException;
import cn.estsh.impp.framework.boot.exception.ImppExceptionBuilder;
import cn.estsh.impp.framework.boot.exception.ImppExceptionEnum;
import cn.estsh.impp.framework.boot.util.ImppRedis;
import cn.estsh.impp.framework.boot.util.ResultBean;
import cn.estsh.impp.framework.boot.util.ValidatorBean;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authc.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;

/**
 * @Description :
 * @Reference :
 * @Author : Adair Peng
 * @CreateDate : 2018-12-19 15:31
 * @Modify:
 **/
@RestController
@Api(description = "非权限服务")
@RequestMapping("/impp/white")
public class WhiteController extends CoreBaseController {

    public static final Logger LOGGER = LoggerFactory.getLogger(WhiteController.class);

    @Autowired
    private ISysLocaleLanguageService sysLocaleLanguageService;

    @Autowired
    private ISystemLoginService systemLoginService;

    @Autowired
    private ISysUserService userService;

    @Autowired
    private IPersonnelService personnelService;

    @Autowired
    private ISystemInitService systemInitService;

    @Resource(name="redisRes")
    private ImppRedis redisRes;

    @GetMapping(value = "/sys-locale-language/list")
    @ApiOperation(value = "查询可用语言",notes = "查询可用语言")
    public ResultBean listSysLocaleLanguage(){
        try {
            List sysLocaleLanguageList = sysLocaleLanguageService.findSysLocaleLanguageByStatus(CommonEnumUtil.TRUE_OR_FALSE.TRUE.getValue());
            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultList(sysLocaleLanguageList);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }

    /**
     *
     * @return
     */
    @GetMapping(value="/auth/logout")
    @ApiOperation(value="登出",notes="登出")
    public ResultBean logout(){
        LOGGER.info("用户退出...");
        try {
            AuthUtil.logout();
            return new ResultBean(true,"您已安全退出。").build();
        } catch (ImppBusiException e) {
            return new ResultBean(false,e.getErrorDetail() + "-[解决]" + e.getErrorSolution());
        }
    }

    @GetMapping(value="/auth/login")
    @ApiOperation(value="登陆",notes="登陆")
    public ResultBean login(HttpServletRequest request, String loginName, String loginPwd, String languageCode,
                            @RequestParam(required = false) String ipAddr){
        LOGGER.info("用户登陆 loginName:{} loginPwd:{} languageCode:{}",loginName,loginPwd,languageCode);
        ResultBean result = null;
        try {
            ValidatorBean.checkNotNull(loginName,"用户名不能为空");
            ValidatorBean.checkNotNull(loginPwd,"密码不能为空");
            ValidatorBean.checkNotNull(languageCode,"语言不能为空");
//            ValidatorBean.checkNotNull(ipAddr,"IP 地址不能为空");

            logout();

            SessionUser user = userService.queryUserLogin(loginName,loginPwd.trim(),languageCode);

            String redisKey = CommonConstWords.USER_LOGIN_ERROR + "_" + user.getUser().getId();
            redisCore.deleteKey(redisKey);

            LOGGER.info("会员登陆：{}",user);
            AuthUtil.setSessionObject("languageCode",languageCode);
            result = new ResultBean(true, AuthUtil.getSession().getId().toString(), AuthUtil.getSessionUser());
            result.setUrl("/");

            // 记录登录记录
            recordSysUserLog(user.getUser().getUserInfoId(), loginName,CommonEnumUtil.USER_LOGIN_STATUS.LOGIN_SUCCESS.getValue(), ipAddr);
        } catch (IncorrectCredentialsException e) {
            // 密码错误
            Integer num = systemLoginService.doLoginPasswordError(loginName, ipAddr);
            num = CommonConstWords.USER_LOGIN_ERROR_MAX_NUM - num;
            result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_PASSWORD);
            if(num == 0){
                result.setErrorMsg("密码输入错误。用户已被锁定请联系管理员！");
            }else {
                result.setErrorMsg("密码输入错误。再输入错误"+ num +"次，用户将被锁定。");
            }

            // 记录登录记录
            recordSysUserLog(null, loginName, CommonEnumUtil.USER_LOGIN_STATUS.WRONG_PASSWORD.getValue(), ipAddr);
        } catch (CredentialsException e) {
            // 用户名或密码错误
            result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_NAME);

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.WRONG_USERNAME_OR_PASSWORD.getValue(), ipAddr);
        } catch (LockedAccountException e) {
            // 账号已锁定
            result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_LOCKING);

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.USER_LOGIN_LOCKING.getValue(), ipAddr);
        } catch (UnknownAccountException e) {
            // 用户信息不存在
            result = ResultBean.fail(ImppExceptionEnum.LOGIN_EXCEPTION_USER_INFO_NULL);

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.USER_INFO_NULL.getValue(), ipAddr);
        } catch (AuthenticationException e) {
            // 系统异常
            result = ResultBean.fail(e.getMessage()).setCode(ImppExceptionEnum.SYSTEM_EXCEPTION.getCode());
            result.setErrorMsg(e.getMessage());

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.SYSTEM_ERROR.getValue(), ipAddr);
        } catch (ImppBusiException e) {
            result = ResultBean.fail(e);

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.SYSTEM_ERROR.getValue(), ipAddr);
        } catch (Exception e) {
            result = ResultBean.fail(e.getMessage()).setCode(ImppExceptionEnum.SYSTEM_EXCEPTION.getCode())
                    .setErrorMsg(ImppExceptionEnum.SYSTEM_EXCEPTION.getDescription());

            // 记录登录记录
            recordSysUserLog(null, loginName,CommonEnumUtil.USER_LOGIN_STATUS.SYSTEM_ERROR.getValue(), ipAddr);
        }
        return result;
    }

    private void recordSysUserLog(Long userId, String username,Integer userLoginStatus,String IpAddr){
        SysLogUserLogin log = new SysLogUserLogin();

        log.setUserId(userId);
        log.setLogLoginName(username);
        log.setLogLoginStatus(userLoginStatus);
        log.setLogLoginBrowser(ServletRequestTool.getRequestBrowser(request));
        log.setLogLoginHost(IpAddr);
        log.setLogLoginPlatform(CommonEnumUtil.LOG_LOGIN_PLATFORM.descOf(ServletRequestTool.getRequestOs(request)));
        log.setLogLoginDateTime(TimeTool.getNowTime(true));

        userService.insertSysLogUserLogin(log);
    }

    @GetMapping(value = "/find-language-code")
    @ApiOperation(value = "根据语言代码查询资源")
    public ResultBean findSysLocaleResourceByLanguageCode(String languageCode){
        try {
            ValidatorBean.checkNotNull(languageCode,"语言代码不能为空");
            if (sysLocaleLanguageService.getSysLocaleLanguageByCode(languageCode) == null) {
                throw ImppExceptionBuilder.newInstance()
                        .setSystemID(CommonEnumUtil.SOFT_TYPE.CORE.getCode())
                        .setErrorCode(ImppExceptionEnum.VARIFY_EXCEPTION.getCode())
                        .setErrorDetail("语言不存在")
                        .build();
            }

            // 从缓存获取语言信息
            Map<Object, Object> resourceMap = redisRes.getHashMap(CommonConstWords.REDIS_PREFIX_CACHE_LANGUAGE + languageCode);
            if (resourceMap == null || resourceMap.size() == 0) {
                systemInitService.loadSysLocaleLanguage();
                resourceMap = redisRes.getHashMap(CommonConstWords.REDIS_PREFIX_CACHE_LANGUAGE + languageCode);
            }

            return ResultBean.success("操作成功").setCode(ResourceEnumUtil.MESSAGE.SUCCESS.getCode()).setResultMap(resourceMap);
        }catch(ImppBusiException busExcep){
            return ResultBean.fail(busExcep);
        }catch(Exception e){
            return ImppExceptionBuilder.newInstance().buildExceptionResult(e);
        }
    }
}
