package com.liang.controller;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.liang.common.base.BaseResult;
import com.liang.common.base.BaseController;
import com.liang.common.idgen.IdGenerate;
import com.liang.common.utils.*;
import com.liang.entity.MenuVo;
import com.liang.entity.SysConfigure;
import com.liang.entity.SysLoginEntity;
import com.liang.entity.SysUserInfo;
import com.liang.service.*;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.security.Key;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Handles requests for the application home page.
 */
@Controller
@RequestMapping("/home")
public class HomeController extends BaseController {
    final static Logger logger = LoggerFactory.getLogger(SysRoleInfoController.class);

    @Resource
    private SysUserInfoService sysUserInfoService;

    @Resource
    private SysConfigureService sysConfigureService;

    @Resource
    private SysPermissionInfoService sysPermissionInfoService;

    @Resource
    private RedisUtil redisUtil;

    @Autowired
    private LoginLogService loginLogService;

    private String contextPath;

    @Resource
    private SysLoginService service;

    /**
     * 会话失效时间(单位秒)
     */
    @Value("${KYGK.session-timeout}")
    private int sessionTimeout;
    @Resource
    private SysDictInfoService sysDictInfoService;

    @RequestMapping(value = "/", method = RequestMethod.GET)
    public String home(Model model) {
        String account = getSysUserAccount();
        if (account != null) {
            model.addAttribute("account", account);
            return "home/index";
        } else {
            return "login/login";
        }
    }
    @RequestMapping(value = "/geturl",method = RequestMethod.GET)
    @ResponseBody
    public BaseResult geturl(){
        List<Map<String,String>> maps = sysDictInfoService.queryByCode("logos");
        return BaseResult.success(maps.get(0).get("name"));
    }


    @RequestMapping(value = "/login")
    public String login() {
        return "login/login";
    }


    @RequestMapping(value = "/index", method = RequestMethod.GET)
    public ModelAndView user(HttpServletRequest request, HttpSession session) {
        String account = getSysUserAccount();
        if (account != null) {
            ModelAndView mv = new ModelAndView();
            mv.addObject("account", account);
            mv.setViewName("home/index");
            return mv;
        } else {
            String loginStatus = request.getParameter("loginStatus");

            ModelAndView mv = new ModelAndView();
            if (StringUtils.isNotBlank(loginStatus)) {
                mv.addObject("loginStatus", loginStatus);
            }
            mv.setViewName("login/login");
            return mv;
        }
    }


    /**
     *
     * @param account
     * @return
     */
    @RequestMapping(value = "/getlogin/{account}",method = RequestMethod.POST)
    @ResponseBody
    public BaseResult getlogin(@PathVariable(required = true,value = "account") String account){

        // 获取人员信息
        SysUserInfo userInfo = sysUserInfoService.getUserByAccount(account);
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("userid",userInfo.getUserId());
        SysLoginEntity sysLoginEntity = service.getAll(hashMap);

        if(sysLoginEntity != null){
            return BaseResult.success("-1");

        }else {
            return BaseResult.success("null");
        }

    }

    /**
     * 修改密码页面
     * @param model
     * @return
     */
    @RequestMapping(value = "/updatepw", method = RequestMethod.GET)
    public String updatpw(Model model) {
        String account = getSysUserAccount();
            return "login/add";
    }

    @ApiOperation(value = "用户登录", notes = "用户登录")
    @RequestMapping(value = "/doLogin", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doLogin(HttpSession session,
                              @RequestParam(required = true, defaultValue = "", value = "username") String account,
                              @RequestParam(required = true, defaultValue = "", value = "password") String password,
                              HttpServletRequest request,
                              HttpServletResponse response) {

        logger.info("account:" + account + " password:" + password);
        SysUserInfo userInfo = sysUserInfoService.getUserByAccount(account);

        password = SHA256Utils.SHA256Encode(password);

        if (userInfo != null && userInfo.getPassword().equals(password)) {
            logger.info("LoginController - doLogin - {}登陆成功！", account);
            Map<String, Object> resultMap = new HashMap<>();
            String redisKey = IdGenerate.uuid();
            logger.info("LoginController - doLogin - redisKey = {}", redisKey);
            //放入部门名称
            String dept = sysUserInfoService.getDeptNameByAccount(userInfo.getDeptId());
            userInfo.setDeptName(dept);
            // 存储用户会话信息到redis
            redisUtil.set(SystemConst.SYSTEM_USER_KEY + ":" + redisKey, userInfo, sessionTimeout);

            String token = SystemConst.TOKEN_PREFIX + JwtTokenUtil.createJWT(redisKey);
            resultMap.put(SystemConst.SYSTEM_USER_TOKEN, token);
            // 将token放在cookie中
            CookieUtils.setCookie(response, SystemConst.SYSTEM_USER_TOKEN, token);
            // 保存登录日志
            loginLogService.saveLoginlog(request, account, "0", "用户登录成功！", redisKey);

//            session.setAttribute("user", userInfo);

            return BaseResult.success("登录成功!");
        } else {
            return BaseResult.failure(1,"密码错误，登录失败!");
        }
    }

    /**
     * 查询页面初始化
     *
     * @return
     */
    @RequestMapping(value = "/init", method = RequestMethod.GET)
    public String init() {
        return "permissioninfo/list";
    }


    /**
     * 查询页面初始化
     *
     * @return
     */
    @RequestMapping(value = "/welcome", method = RequestMethod.GET)
    public String welcome() {
        return "home/welcome-2";
    }

    @RequestMapping(value = "/table", method = RequestMethod.GET)
    public String table() {
        return "home/table";
    }

    /**
     * 基本资料
     *
     * @param model
     * @return
     */
    @RequestMapping(value = "/usersetting", method = RequestMethod.GET)
    public String userInfo(Model model) {
        Integer userId = getSysUserId();
        SysUserInfo userInfo = sysUserInfoService.queryById(userId);
        model.addAttribute("userInfo", userInfo);
        return "home/user-setting";
    }

    /**
     * 获取菜单
     *
     * @return
     */
    @RequestMapping(value = "/menuInit", method = RequestMethod.GET)
    @ResponseBody
    public Object menuInit() {
        Map<String, Object> map = getMenuInit();
        return map;
    }

    /**
     * 初始化菜单
     *
     * @return
     */
    private Map<String, Object> getMenuInit() {
        int userId = getSysUserId();

        Map<String, Object> map = new HashMap<>(16);
        Map<String, Object> home = new HashMap<>(16);
        Map<String, Object> logo = new HashMap<>(16);

        List<Map> menuList = sysPermissionInfoService.menuInit(userId);

        // 在herf上拼接上context-path项目上下文
        if (StringUtils.isBlank(contextPath)) {
            contextPath = "";
        }
        if (menuList != null && !menuList.isEmpty()) {
            for (Map item : menuList) {
                String href = (String) item.get("href");
                if (StringUtils.isNotBlank(href)) {
                    item.put("href", contextPath + href);
                }
            }
        } else {
            // 此处修改是为了避免用户首次注册时，因为无菜单信息，进不去首页的情况。
            menuList = new ArrayList<>();
        }

        List<MenuVo> menuInfo = new ArrayList<>();

        for (Map temp : menuList) {
            MenuVo menuVO = new MenuVo();
            menuVO.setPermissionId((String) temp.get("permission_id"));
            menuVO.setParentId((String) temp.get("parent_id"));
            menuVO.setHref((String) temp.get("href"));
            menuVO.setTitle((String) temp.get("title"));
            menuVO.setIcon((String) temp.get("icon"));
            menuVO.setTarget((String) temp.get("target"));
            menuInfo.add(menuVO);
        }
        // 将菜单转成树结构
        map.put("menuInfo", toTree(menuInfo, "0"));

        SysConfigure config = sysConfigureService.queryById(1);

        home.put("title", "首页");
        // 控制器路由,自行定义
        home.put("href", contextPath + config.getHomepageHref());

        logo.put("title", config.getSystemName());
        logo.put("image", config.getSystemLogo());
        logo.put("href", "");

        map.put("homeInfo", home);
        map.put("logoInfo", logo);
        return map;
    }


    /**
     * 获取菜单的树状结构（双重遍历法list转tree）
     *
     * @param menuList 菜单列表
     * @param topPid   顶级ID
     * @return
     */
    private List<MenuVo> toTree(List<MenuVo> menuList, String topPid) {
        Map<String, List<MenuVo>> menuMap = new HashMap<>();

        menuList.forEach(node -> {
            List<MenuVo> children = menuMap.getOrDefault(node.getParentId(), new ArrayList<>());
            children.add(node);
            menuMap.put(node.getParentId(), children);
        });

        menuList.forEach(node -> node.setChild(menuMap.get(node.getPermissionId())));

        List<MenuVo> result = menuList.stream().filter(v -> v.getParentId().equals(topPid)).collect(Collectors.toList());
        return result;
    }

    /**
     * 修改密码页面
     *
     * @return
     */
    @RequestMapping(value = "/userpassword", method = RequestMethod.GET)
    public String updatePassword() {
        return "home/user_password";
    }

    /**
     * 修改密码操作
     *
     * @param old_password
     * @param new_password
     * @return
     */
    @RequestMapping(value = "/doUpdatePassword", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doUpdatePassword(@RequestParam("old_password") String old_password,
                                       @RequestParam("new_password") String new_password) {

        logger.info("HomeController - doUpdatePassword - start - old_password = " + old_password);
        logger.info("HomeController - doUpdatePassword - start - new_password = " + new_password);
        // 创建一个 Date 对象并获取当前时间
        Date currentTime = new Date();

        // 创建 SimpleDateFormat 对象来定义时间格式
        SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

        // 使用 format() 方法对时间进行格式化
        String formattedTime = formatter.format(currentTime);

        Integer userId = getSysUserId();
        SysUserInfo userInfo = sysUserInfoService.queryById(userId);
        // 获取数据库库里的加密后的密码
        String md5Password = userInfo.getPassword();
        // 再进行加密两次，才是正确密码
        old_password = SHA256Utils.SHA256Encode(old_password);

        // 旧密码验证成功
        if (md5Password.equals(old_password)) {
            new_password = SHA256Utils.SHA256Encode(new_password);
            userInfo.setPassword(new_password);

            int num = sysUserInfoService.resetPass(userInfo);
            if (num > 0) {
                SysLoginEntity sysLoginEntity = new SysLoginEntity();
                sysLoginEntity.setUserid(userId);
                sysLoginEntity.setXgsj(formattedTime);
                int mum = service.LoginInsert(sysLoginEntity);
                return BaseResult.success("密码修改成功");
            }else{
                return BaseResult.failure("修改密码失败");}
        } else {
            return BaseResult.failure("原密码验证失败");
        }
    }

    /**
     * 退出登录
     *
     * @return
     */
    @RequestMapping(value = "/outLogin", method = RequestMethod.GET)
    public String outLogin() {
        String userKey = SecurityUtil.getUserKey();
        // 先从redis里面拿出菜单信息，拿不到的话，再去手动查询
        Object object = redisUtil.get(SystemConst.SYSTEM_USER_MENU + ":" + userKey);
        logger.info("IndexController - outLogin - start");
        String token = getUserKey();
        // 删除用户的会话信息，即强制退出登录
        redisUtil.del(SystemConst.SYSTEM_USER_KEY + ":" + token);
        //回到登陆页面
        return "redirect:" + contextPath + "/home/login";
    }

    /**
     * 修改用户信息
     *
     * @return
     */
    @RequestMapping(value = "/doUpdate", method = RequestMethod.POST)
    @ResponseBody
    public BaseResult doUpdate(@RequestParam(value = "userId") Integer userId,
                               @RequestParam(value = "phone") String phone,
                               @RequestParam(required = false, defaultValue = "", value = "email") String email) {

        SysUserInfo userInfo = new SysUserInfo();
        userInfo.setUserId(userId);
        userInfo.setPhone(phone);
        userInfo.setEmail(email);
        userInfo.setUpdateUser(getSysUserId());

        int num = sysUserInfoService.update(userInfo);
        if (num > 0) {
            return BaseResult.success("基本资料修改成功");
        } else {
            return BaseResult.failure("基本资料修改失败");
        }
    }
}
