package ${basePackage}.action.ajax.system;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.multipart.MultipartFile;
import ${basePackage}.frame.auth.LocalData;
import ${basePackage}.frame.auth.Token;
import ${basePackage}.frame.base.BaseResponse;
import ${basePackage}.frame.base.ErrorType;
import ${basePackage}.frame.excel.WExcel;
import ${basePackage}.frame.excel.exception.ReadErrorException;
import ${basePackage}.frame.excel.exception.TemplateNotMatchException;
import ${basePackage}.frame.utils.CookieUtil;
import ${basePackage}.frame.utils.LogUtil;
import ${basePackage}.frame.utils.MD5Util;
import ${basePackage}.frame.utils.MapperUtil;
import ${basePackage}.frame.utils.RequestUtil;
import ${basePackage}.frame.utils.ResponseUtil;
import ${basePackage}.frame.utils.ValidationUtil;
import ${basePackage}.module.system.ent.User;
import ${basePackage}.module.system.mgr.TokensManager;
import ${basePackage}.module.system.mgr.UserManager;
import ${basePackage}.module.system.req.TokensCreateRequest;
import ${basePackage}.module.system.req.TokensLogoutRequest;
import ${basePackage}.module.system.req.UserCreateRequest;
import ${basePackage}.module.system.req.UserDeleteRequest;
import ${basePackage}.module.system.req.UserFindRequest;
import ${basePackage}.module.system.req.UserGetRequest;
import ${basePackage}.module.system.req.UserLoginRequest;
import ${basePackage}.module.system.req.UserLogoutRequest;
import ${basePackage}.module.system.req.UserUpdateRequest;
import ${basePackage}.module.system.rsp.TokensCreateResponse;
import ${basePackage}.module.system.rsp.TokensLogoutResponse;
import ${basePackage}.module.system.rsp.UserCreateResponse;
import ${basePackage}.module.system.rsp.UserDeleteResponse;
import ${basePackage}.module.system.rsp.UserFindResponse;
import ${basePackage}.module.system.rsp.UserGetResponse;
import ${basePackage}.module.system.rsp.UserLoginResponse;
import ${basePackage}.module.system.rsp.UserLogoutResponse;
import ${basePackage}.module.system.rsp.UserUpdateResponse;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.UUID;

public class UserAjax {

    @Value("${r'${web.url.auth.admin}'}")
    private String admin;
    @Value("${r'${web.url.auth.pwd}'}")
    private String pwd;
    @Autowired
    private TokensManager tokensManager;
    @Autowired
    private UserManager userManager;

    public UserCreateResponse create(UserCreateRequest request, Token token) {
        return userManager.create(request, token);
    }

    public UserDeleteResponse delete(UserDeleteRequest request, Token token) {
        return userManager.delete(request, token);
    }

    public UserUpdateResponse update(UserUpdateRequest request, Token token) {
        return userManager.update(request, token);
    }

    public UserFindResponse find(UserFindRequest request, Token token) {
        return userManager.find(request, token);
    }

    public UserGetResponse get(UserGetRequest request, Token token) {
        return userManager.get(request, token);
    }

    public UserLoginResponse login(UserLoginRequest request, Token token, HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse) {
        UserLoginResponse response = new UserLoginResponse();

        ValidationUtil.validate(request, response);
        if (response.hasError()) {
            return response;
        }

        if (request.getUsername().equals(admin)) {//超级管理员登录
            String generatePwd = MD5Util.generatePwd(request.getPassword());
            if (!generatePwd.equals(pwd)) {
                response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
            } else {
                Date current = new Date();
                Calendar instance = Calendar.getInstance();
                instance.setTime(current);
                instance.add(Calendar.HOUR_OF_DAY, 1);//默认一个小时内有效

                TokensCreateRequest tokensCreateRequest = new TokensCreateRequest();
                tokensCreateRequest.setToken(UUID.randomUUID().toString());
                tokensCreateRequest.setUserId(0L);
                tokensCreateRequest.setUserName(admin);
                tokensCreateRequest.setLoginTime(current);
                tokensCreateRequest.setValidTime(instance.getTime());
                tokensCreateRequest.setValid(true);
                tokensCreateRequest.setDeptId(null);
                tokensCreateRequest.setDeptCode(null);
                tokensCreateRequest.setDeptName(null);
                tokensCreateRequest.setTerminalType("WEB");
                tokensCreateRequest.setTerminalIp(RequestUtil.getIp(httpServletRequest));
                tokensCreateRequest.setTerminalInfo(RequestUtil.getUserAgent(httpServletRequest));
                TokensCreateResponse tokensCreateResponse = tokensManager.create(tokensCreateRequest, LocalData.getSysToken());

                if (tokensCreateResponse.hasError()) {
                    response.addErrors(tokensCreateResponse.getErrors());
                    return response;
                }
                Cookie cookie = CookieUtil.newCookie("token", tokensCreateRequest.getToken());
                cookie.setPath("/");
                httpServletResponse.addCookie(cookie);
                response.setToken(tokensCreateRequest.getToken());
            }
        } else {//管理员登录
            UserFindRequest userFindRequest = new UserFindRequest();
            userFindRequest.setUserName(request.getUsername());
            UserFindResponse userFindResponse = userManager.find(userFindRequest, LocalData.getSysToken());

            if (userFindResponse.hasError()) {
                response.addErrors(userFindResponse.getErrors());
                return response;
            } else if (userFindResponse.getResult().size() == 0) {
                response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
                return response;
            } else if (userFindResponse.getResult().size() > 1) {
                response.addError(ErrorType.BUSINESS_ERROR, "用户信息异常!");
                return response;
            }

            User user = userFindResponse.getResult().get(0);

            String generatePwd = MD5Util.generatePwd(request.getPassword());
            if (!generatePwd.equals(user.getUserPwd())) {
                response.addError(ErrorType.BUSINESS_ERROR, "用户名或密码错误!");
                return response;
            }

            Date current = new Date();
            Calendar instance = Calendar.getInstance();
            instance.setTime(current);
            instance.add(Calendar.HOUR_OF_DAY, 1);//默认一个小时内有效

            TokensCreateRequest tokensCreateRequest = new TokensCreateRequest();
            tokensCreateRequest.setToken(UUID.randomUUID().toString());
            tokensCreateRequest.setUserId(user.getId());
            tokensCreateRequest.setUserName(user.getUserName());
            tokensCreateRequest.setLoginTime(current);
            tokensCreateRequest.setValidTime(instance.getTime());
            tokensCreateRequest.setValid(true);
            tokensCreateRequest.setDeptId(user.getDeptId());
            tokensCreateRequest.setDeptCode(user.getDeptCode());
            tokensCreateRequest.setDeptName(user.getDeptName());
            tokensCreateRequest.setTerminalType("WEB");
            tokensCreateRequest.setTerminalIp(RequestUtil.getIp(httpServletRequest));
            tokensCreateRequest.setTerminalInfo(RequestUtil.getUserAgent(httpServletRequest));
            TokensCreateResponse tokensCreateResponse = tokensManager.create(tokensCreateRequest, LocalData.getSysToken());

            if (tokensCreateResponse.hasError()) {
                response.addErrors(tokensCreateResponse.getErrors());
                return response;
            }
            Cookie cookie = CookieUtil.newCookie("token", tokensCreateRequest.getToken());
            httpServletResponse.addCookie(cookie);
            response.setToken(tokensCreateRequest.getToken());
        }

        return response;
    }

    public UserLogoutResponse logout(UserLogoutRequest request, Token token) {
        UserLogoutResponse response = new UserLogoutResponse();

        if (token != null) {
            TokensLogoutRequest tokensLogoutRequest = new TokensLogoutRequest();
            tokensLogoutRequest.setToken(token.getToken());
            TokensLogoutResponse tokensLogoutResponse = tokensManager.logout(tokensLogoutRequest, LocalData.getSysToken());
            if (tokensLogoutResponse.hasError()) {
                response.addErrors(tokensLogoutResponse.getErrors());
                return response;
            }
        }
        CookieUtil.clearCookie("token");
        return response;
    }

    public Object template() {
        return ResponseUtil.apply(new WExcel<>(User.class));
    }

    public Object exports(UserFindRequest request, Token token) {
        UserFindResponse response = userManager.find(request, token);
        if (response.hasError()) {
            return response;
        } else if (response.getTotalCount() == 0) {
            response.addError(ErrorType.BUSINESS_ERROR, "导出数据为空");
            return response;
        }
        return ResponseUtil.apply(new WExcel<>(User.class).loadData(response.getResult()));
    }

    public Object imports(MultipartFile file) {
        BaseResponse baseResponse = new BaseResponse();
        try {
            WExcel sheet = new WExcel<>(User.class).loadData(file.getBytes(), new WExcel.Processor<User>() {
                @Override
                public List<String> exec(User o) {
                    UserCreateRequest request = MapperUtil.map(o, UserCreateRequest.class);
                    return ValidationUtil.validate(request);
                }
            });

            if (sheet.hasError()) {
                return ResponseUtil.apply(sheet.getBytes(), sheet.getName() + "-检查.xlsx");
            } else {
                return baseResponse;
            }
        } catch (IOException e) {
            e.printStackTrace();
            LogUtil.dumpException(e);
            baseResponse.addError(ErrorType.BUSINESS_ERROR, "上传文件出错");
        } catch (TemplateNotMatchException | ReadErrorException e) {
            baseResponse.addError(ErrorType.BUSINESS_ERROR, e.getMessage());
        }
        return baseResponse;
    }
}
