package com.mortals.xhx.base.login.web;

import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.Rest;
import com.mortals.framework.service.IAuthTokenService;
import com.mortals.framework.service.ICacheService;
import com.mortals.framework.service.IUser;
import com.mortals.framework.util.DateUtils;
import com.mortals.framework.util.StringUtils;
import com.mortals.framework.web.BaseCRUDJsonBodyMappingController;
import com.mortals.xhx.base.system.menu.model.MenuEntity;
import com.mortals.xhx.base.system.menu.service.MenuService;
import com.mortals.xhx.base.system.resource.service.ResourceService;
import com.mortals.xhx.base.system.user.model.UserEntity;
import com.mortals.xhx.base.system.user.service.UserService;
import com.mortals.xhx.common.key.RedisKey;
import com.mortals.xhx.common.utils.MenuEncodeUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.List;
import java.util.Set;

import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED;
import static com.mortals.xhx.common.key.ErrorCode.ERROR_TOKEN_EXPIRED_CONTENT;

@RestController
@Slf4j
@RequestMapping("login")
public class LoginController extends BaseCRUDJsonBodyMappingController<UserService, UserEntity, Long> implements InitializingBean {

    @Autowired
    private ResourceService resourceService;
    @Autowired
    private MenuService menuService;
    @Autowired
    private ICacheService cacheService;
    @Autowired
    private IAuthTokenService authTokenService;
    @Autowired
    private UserService userService;


    @RequestMapping("login")
    public String login(@RequestBody LoginForm loginForm) throws Exception {
        JSONObject ret = new JSONObject();
        JSONObject data = new JSONObject();
        String loginName = loginForm.getLoginName();
        String password = loginForm.getPassword();
        //  String securityCode = loginForm.getSecurityCode();
        String ip = super.getRequestIP(request);
        if (StringUtils.isEmpty(loginName) || StringUtils.isEmpty(password)) {
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, "未获取到用户信息，请重新登录");
            return ret.toJSONString();
        }
        UserEntity userEntity = null;
        try {
//            loginForm.validate();
//            boolean result = validCodeService.doCheckImageValidCode(request.getSession().getId(), ip, securityCode);
//            if (!result) {
//                recordSysLog(request, userEntity, "登录验证码不正确或已过期!");
//                ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
//                ret.put(KEY_RESULT_MSG, "登录验证码不正确或已过期!");
//                return ret.toJSONString();
//            }
            userEntity = userService.doLogin(loginName, password, ip);
            userEntity.setLastLoginAddress(ip);
            //  saveCurrUser(request, response, userEntity);
            recordSysLog(request, userEntity, "用户登录系统成功!");

            String tmpToken = userEntity.getId() + ":" + IdUtil.fastSimpleUUID();
            userEntity.setToken(tmpToken);
            userEntity.setExpireTime(DateUtils.addCurrDate(1).getTime());
            String token = authTokenService.createToken(userEntity);
            data.put("token", token);
            // 返回拥有的菜单数据
            Set<String> urls = resourceService.findUrlSetByUserId(userEntity.getId());
            List<MenuEntity> outlookBarList = menuService.findTreeMenu(userEntity, urls);
            String currUserName = userEntity.getRealName();
            if (currUserName == null || currUserName.trim().length() == 0) {
                currUserName = "管理员";
            }

            data.put("currUserName", currUserName);
            data.put("barList", outlookBarList);
            data.put("id", userEntity.getId());
            data.put("userType", userEntity.getUserType());

            ret.put(KEY_RESULT_DATA, data);
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
            ret.put(KEY_RESULT_MSG, "用户登录系统成功!");
            ret.put("resources", urls);

            return ret.toJSONString();
        } catch (Exception e) {
            log.error("login error ", e);
            if (userEntity == null) {
                userEntity = new UserEntity();
                userEntity.setLoginName(loginName);
            }
            ret.put(KEY_RESULT_CODE, VALUE_RESULT_FAILURE);
            ret.put(KEY_RESULT_MSG, super.convertException(e));
            return ret.toJSONString();
        }
    }

    @RequestMapping("logout")
    public void logout(HttpServletRequest request, HttpServletResponse response) throws Exception {
        recordSysLog(request, "退出登录");
        super.removeCurrUser(request);
    }

    @RequestMapping("index")
    public String index() throws Exception {
        JSONObject ret = new JSONObject();
        IUser user = this.getCurUser();
        if (user == null) {
            return JSONObject.toJSONString(Rest.fail(ERROR_TOKEN_EXPIRED, ERROR_TOKEN_EXPIRED_CONTENT));
        }
        Set<String> urls = resourceService.findUrlSetByUserId(user.getId());
        log.info("userId:{},urls:{}", user.getId(),JSON.toJSONString(urls));
        List<MenuEntity> outlookBarList = menuService.findTreeMenu(user, urls);
        String currUserName = user.getRealName();
        if (currUserName == null || currUserName.trim().length() == 0) {
            currUserName = "管理员";
        }
        JSONObject data = new JSONObject();

        String token = authTokenService.getToken(request);
        data.put("token", token);
        data.put("currUserName", currUserName);
        data.put("barList", outlookBarList);
        data.put("id", user.getId());
        data.put("userType", user.getUserType());
        ret.put(KEY_RESULT_DATA, data);
        cacheService.hset(RedisKey.KEY_USER_MENU_CACHE, user.getId().toString(), MenuEncodeUtil.generateMenuUrlCode(urls));

        ret.put(KEY_RESULT_CODE, VALUE_RESULT_SUCCESS);
        ret.put(KEY_RESULT_MSG, "用户登录系统成功!");
        ret.put("resources", urls);
        return ret.toJSONString();
    }





    @Override
    public void afterPropertiesSet() throws Exception {
        log.info("初始化加载登录。。。");
    }
}
