package org.example.Api;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.*;
import jakarta.servlet.http.*;
import org.example.Utils.LanguageUtil;
import org.example.Entity.BaseResponse.BaseResponse;
import org.example.Entity.CusException.CusException;
import org.example.Entity.System.LoginUserInfo;
import org.example.Entity.Attributes.*;
import org.example.Impl.BaseImpl;
import org.example.Utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.servlet.support.RequestContext;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.time.temporal.Temporal;
import java.util.*;
import java.util.zip.GZIPOutputStream;

import org.example.Enums.LoginCode;

import static org.example.Utils.NativeExtensionUtils.*;

/**
 * ==============================================================================
 * 功能描述：BaseHandler  对外开放的接口父类
 * ==============================================================================
 */
public abstract class BaseHandler {
    private static final Logger log = LoggerFactory.getLogger(BaseHandler.class);

    protected HttpServletRequest Request;
    protected HttpServletResponse Response;
    protected HttpSession Session;
    protected Cookie Cookie;
    protected ServletContext Application;
    protected HttpServletRequest context;
    protected String methodName, ModuleId, MenuId, MenuCode, language;
    protected BaseResponse response;
    protected int currPage = 0, pageSize = 0, startsize = 0;
    protected boolean isCustomer = false, isWindowsDirver = true; // IsCustomer:标识为游客客户端 IsWindowsDirver:PC端访问
    protected LocalDateTime startTime, endTime;

    private static long requestCount = 0, maxPMins = 0, lastCount = 0, lastMins = 0;
    private static LocalDateTime startDate = LocalDateTime.now();
    private static LocalDateTime maxPDate = LocalDateTime.now();

    public RequestContext requestContext;

    @Autowired
    private ObjectMapper objectMapper;

    protected String getUserName() {
        return getUser() != null ? getUser().UserName : "";
    }

    protected String getUserId() {
        return getUser() != null ? getUser().UserId : "";
    }

    protected LoginUserInfo _user;

    protected LoginUserInfo getUser() {

        return _user = getBImpl().getUser();


    }

    protected String getUserSessionName() {
        return getBImpl().getUserSessionName();
    }

    protected String getSessionId() {
        return getBImpl().getSessionId();
    }

    protected String getDriver() {
        return getBImpl().getDriver();
    }

    protected String getAppDomain() throws UnsupportedEncodingException {
        return getBImpl().getAppDomain();
    }

    /**
     * 附件路径
     */
    protected String getAttcPath() {
        return getBImpl().getAttcPath();
    }

    //【200426】未找到的提示
    protected String notFindModuleMsg;

    protected DbOperator getDbOperator() {
        return getDbOprator();
    }

    protected DbOperator getDbOprator() {
        return getBImpl().getDbOperator();
    }

    private BaseImpl _bImpl = null;

    protected BaseImpl getBImpl() {
        if (_bImpl == null) {
            _bImpl = new BaseImpl();
        }
        return _bImpl;
    }

    public void processRequest(HttpServletRequest ctx) throws IOException, ServletException {
        boolean isDebug = toBoolean(WebConfigUtil_web.get("debug", ""));
        if (!isDebug) {
            // 对应C#的DEBUG编译符号判断，可根据实际环境调整
            isDebug = false;
        }

        _bImpl = null;
        startTime = LocalDateTime.now();

        // 网站访问量统计
        requestCount++;
        int mins = (int) Duration.between(startDate, LocalDateTime.now()).toMinutes();
        if (mins > lastMins) {
            lastMins = mins;
            if (requestCount - lastCount > maxPMins) {
                maxPDate = LocalDateTime.now();
                maxPMins = requestCount - lastCount;
            }
            lastCount = requestCount;
        }

        SingleUserHandler.cacheKey = (getUserSessionName());
        context = ctx;
        Session = ctx.getSession();
        Application = ctx.getServletContext();
        initSystemParams(ctx);
        response = new BaseResponse();
        response.setSuccess(false);
        response.setMsg("");

        methodName = getMethod();
        Class<?> type = this.getClass();
        if (isNullOrEmpty(methodName)) {
            response.setSuccess(false);
            response.setMsg(LanguageUtil.WrongInterfaceName);
            writeResponse();
            return;
        }

        Method method = null;
        try {
//            out.println(method + " me");
            method = type.getMethod(methodName);

        } catch (NoSuchMethodException e) {
            log.warn(String.valueOf(e.getMessage() + "Err:ApiFunctionName,Please CheckOut!!"));
            response.setSuccess(false);
            response.setMsg(LanguageUtil.WrongInterfaceName);
            writeResponse();
            return;
        }

        String mName = methodName.substring(0, 1) +
                methodName.substring(methodName.length() - 2, methodName.length() - 1) +
                "_" + methodName.length();
        mName = mName.toUpperCase();
//        out.println(mName + "mname");
        try {
            RequestCheckAttribute webCheck = AttributeUtils.getAttribute(method);
            if (webCheck == null) {
                webCheck = AttributeUtils.getCustomAttribute(type, RequestCheckAttribute.class);
            }
            if (webCheck != null) {
                webCheck.setBImpl(getBImpl()); // 现在可以正常调用setter
            }

            log.debug(String.valueOf("当前方法：" + methodName + "，匹配的CheckParams：" + (webCheck != null ? webCheck.CheckParams : "null") +
                    "，匹配的Log：" + (webCheck != null ? webCheck.Log : "null") +
                    "，匹配的CheckLogin：" + (webCheck != null ? webCheck.CheckLogin : "null")));
//            out.println("webcheck是"+webCheck);
            // 登录检查
            boolean declaredPublic = webCheck != null && !webCheck.CheckLogin;
            boolean allowedPublic = declaredPublic && PublicApiRegistry.isPublicEndpoint(type, methodName);
            boolean requiresLogin = webCheck == null || webCheck.CheckLogin || (declaredPublic && !allowedPublic);
            if (requiresLogin && !checkLoginByPro()) {
//            if (true && !checkLoginByPro()) {
                goLogin();
            } else {
                if (!isNullOrEmpty(getUserName())) {
                    ActiveUserUtil.active(
                            (getUser() != null && !isNullOrEmpty(getUser().Token) ?
                                    getUser().Token.hashCode() + "" : getSessionId()),
                            getUserName()
                    );
                }

                String[] errMsg = new String[1];
                if (webCheck == null || webCheck.validParams(errMsg)) {
                    getDbOperator().setCloseCon(true); // 使用同一个连接，提高速度
                    initReqPms();
//                    out.println(method + " 1me " + objectMapper.writeValueAsString(response) + " re ");
                    if (webCheck != null && webCheck.Cache && toBoolean(WebConfigUtil_web.get("Cache", ""))) {
                        Method finalMethod = method;
//                        out.println(method + " me1.5" + objectMapper.writeValueAsString(response) + "re");
                        String result = (String) webCheck.getCacheVal(this, () -> {
                            try {
                                finalMethod.invoke(this);
//                                out.println(finalMethod + " 2me" + objectMapper.writeValueAsString(response) + "re");
                                return objectMapper.writeValueAsString(response);
                            } catch (Exception e) {
                                throw new RuntimeException(e);
                            }
                        });
                        response.setEncodedResult(result);
                    } else {
//                        out.println(method + " 3me" + objectMapper.writeValueAsString(response) + "re");
                        method.invoke(this);
                    }
                    log.debug(String.valueOf(response.getData() + "dataS"));
//                    getDbOperator().dispose();
                    endTime = LocalDateTime.now();
                    String logName = (webCheck == null) ? mName : (webCheck.Name != null ? webCheck.Name : mName);

                    double t = Duration.between(startTime, endTime).toMillis();
                    String idValue = getBImpl().Request("idValue");

                    StringBuilder msg = new StringBuilder();
                    if (isNullOrEmpty(idValue)) {
                        msg.append(String.format("执行%s,耗时%sms", logName, t));
                        if (!isNullOrEmpty(ModuleId)) {
                            msg.append(String.format(",模块：%s", ModuleId));
                        }
                        if (isDebug) {
                            msg.append(objectMapper.writeValueAsString(getBImpl().getAllRequest()));
                        }
                    } else {
                        msg.append(String.format("执行%s,耗时%sms,模块：%s,主键：%s", logName, t, ModuleId, idValue));
                        if (isDebug) {
                            msg.append(objectMapper.writeValueAsString(getBImpl().getAllRequest()));
                        }
                    }

                    if (webCheck == null || webCheck.Log) {
                        LoggerHandler.info(this, msg.toString());
                    }

                    if (t > 2000) {
                        LoggerHandler.dbLog(this, getDbOperator(), "warn", ModuleId, logName, JSON.Encode(getBImpl().getAllRequest()), t, "", null);
                    }
                } else {
                    response.setSuccess(false);
                    response.setMsg(errMsg[0]);
                }

                if (webCheck == null || (webCheck.WriteRespose && response.isWriteResponse())) {
                    if (response.isSuccess() && isNullOrEmpty(response.getToken()) &&
                            !"LoginOut".equals(methodName) && getUser() != null && !isNullOrEmpty(getUser().Token)) {
                        response.setToken(JwtHelp.refreshToken(getUser(), getUser().Token, 7200));
                        if (!isNullOrEmpty(response.getToken())) {
                            getUser().Token = (response.getToken());
                            BaseImpl.setSessionVal(getUserSessionName(), getUser());
                        }
                    }

                    if (!isNullOrEmpty(response.getMsg()) &&
                            response.getMsg().contains("execute sql error")) {
                        response.setMsg(response.getMsg().substring(
                                response.getMsg().indexOf("execute sql error")));
                    }

                    writeResponse();
                }
            }
        } catch (Exception ex) {
//            System.err.println("捕获到异常类型：" + ex.getClass().getName());
//            System.err.println("异常消息：" + ex.getCause().getMessage());
            log.error("Exception caught", ex); // 打印完整堆栈，查看异常来源

            String idValue = getBImpl().Request("idValue");
            String errMsg = ExceptionSummaryUtil.summarizeForClient(ex);
            boolean sqlExecuteError = ExceptionSummaryUtil.containsMessage(ex, "execute sql error");

            log.debug(String.valueOf("Err:errMsg 方法里有异常错误,排查——>" + methodName));

            String errStackMsg = "错误：" + errMsg;

            StringBuilder msg = new StringBuilder();
            if (isNullOrEmpty(idValue)) {
                msg.append(String.format("接口：%s,%s", mName, errStackMsg));
            } else {
                msg.append(String.format("接口：%s,模块：%s,主键：%s,%s", mName, ModuleId, idValue, errStackMsg));
            }

            Response.reset();
            response = new BaseResponse();
            response.setSuccess(false);
            response.setMsg(LanguageUtil.ServerError +
                    "<a href='" + getAppDomain() + "/logs/err.txt' style='color:blue;' target='_blank'>查看详情</a>" + msg);

            if (isDebug) {
                response.setMsg(errMsg);
            }

            if (!(ex instanceof CusException) || ((CusException) ex).Log) {
                if (isDebug || !sqlExecuteError) {
                    LoggerHandler.error(msg, ex);
                } else {
                    LoggerHandler.dbLog(this, getDbOperator(), "error", ModuleId, methodName,
                            JSON.Encode(getBImpl().getAllRequest()), 0, msg.toString().replace(mName, methodName), ex);
                }
            }

            writeResponse();
        } finally {
            if (getBImpl() != null) {
                getBImpl().getReqHandler().clearPms();
            }
        }
    }

    /**
     * 验证完后，初始化参数
     */
    protected void initReqPms() {
        language = getBImpl().Request("lg", "cn");
        currPage = parseInt(getBImpl().Request("currPage", getBImpl().Request("page", "1")));
        pageSize = parseInt(getBImpl().Request("pageSize", getBImpl().Request("limit", "-1")));
        isWindowsDirver = toBoolean(getBImpl().Request("windowsDirver", "1"));

        ModuleId = getBImpl().Request("ModuleId").split(",")[0]; // PC端用
        MenuId = parseInt(getBImpl().Request("MenuId", getBImpl().Request("menuid"))) + ""; // 通用
        MenuCode = getBImpl().Request("menucode"); // 手机端用
        ModuleId = isNullOrEmpty(ModuleId) ? MenuCode : ModuleId;

        if (!isNullOrEmpty(ModuleId)) {
            ModuleId = ModuleId.replace("\r", "").replace("\n", "");
        }
        MenuCode = ModuleId;

        startsize = (currPage - 1) * pageSize;
        startsize = Math.max(startsize, 0);

        // 【200426】未找到的msg
        notFindModuleMsg = "未找到模块号【" + ModuleId + "】的配置数据，请检查相应模块的配置是否正确！可能是多余的空格、回车，数字字母写错，模块暂未配置等情况！";
    }

    protected String getMethod() {
        if (requestContext != null) {
            // 从请求上下文中获取路由数据（模拟RouteValueDictionary）
            Map<String, Object> routeValues = getRouteValues(requestContext);
            if (routeValues.containsKey("method")) {
                Object methodValue = routeValues.get("method");
                return methodValue != null ? methodValue.toString() : "";
            } else {
                return getBImpl().Request("method", getBImpl().Request("action"));
            }
        }
        return getBImpl().Request("method", getBImpl().Request("action"));
    }

    // 辅助方法：获取路由参数（根据实际框架实现）
    private Map<String, Object> getRouteValues(RequestContext requestContext) {
        // 1. 若使用Spring MVC，可通过RequestContextHolder获取请求参数
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpServletRequest request = attributes.getRequest();
            // 2. 转换请求参数为Map（包含路由参数和请求参数）
            return FormParamUtil.convertToMyBatisParamMap(request);
        }
        return new HashMap<>();
    }

//    public static void gZipEncodePage() {
//        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).Request();
//        HttpServletResponse response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
//
//        String acceptEncoding = request.getHeader("Accept-Encoding");
//        if (!isNullOrEmpty(acceptEncoding) &&
//                (acceptEncoding.contains("gzip") || acceptEncoding.contains("deflate"))) {
//
//            if (acceptEncoding.contains("gzip")) {
//
//                response.setHeader("Content-Encoding", "gzip");
//                response.setOutputStream(new GZIPOutputStream(response.getOutputStream()));
//
//            } else if (acceptEncoding.contains("deflate")) {
//                // 实现deflate压缩
//            }
//        }
//    }

    private static String webVer = WebConfigUtil_web.get("WebVersion", "1.0.0.0");

    /**
     * 回写数据
     */
    protected void writeResponse() throws IOException {
        HttpServletResponse resp = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
        resp.setHeader("WebAppVer", webVer);

        if (resp.isCommitted()) {
            log.debug(String.valueOf("响应已提交，跳过重复写入：" + Request.getRequestURI()));
            return;
        }

//        String content = isNullOrEmpty(response.getEncodedResult()) ?
//                objectMapper.writeValueAsString(response) : response.getEncodedResult();
        String content = isNullOrEmpty(response.getEncodedResult()) ?
                JSON.Encode(response) : response.getEncodedResult();

        String recodings = Request.getHeader("Response-Encoding");
        boolean gzipResponse = recodings != null && recodings.contains("gzip");

        if (Request.getHeader("Referer") != null) {
            String refDom = getDomainFromUrl(Request.getHeader("Referer"));
            String curUrl = getDomainFromUrl(Request.getRequestURL().toString());

            if (!refDom.equals(curUrl)) {
                resp.setHeader("Access-Control-Allow-Origin", refDom);
                resp.setHeader("Access-Control-Allow-Credentials", "true");
            }
        } else {
            resp.setHeader("Access-Control-Allow-Origin", "*");
        }

        if (gzipResponse) {
            content = URLEncoder.encode(content, StandardCharsets.UTF_8);
            content = GZipUtil.gZip(content);
            resp.setHeader("Response-Encoding", "gzip");
        }

        resp.setContentType("text/plain;charset=UTF-8");
        if (!Response.isCommitted()) {
            try (OutputStream os = resp.getOutputStream()) {
                os.write(content.getBytes(StandardCharsets.UTF_8));
                os.flush();
            } catch (Exception e) {
                // 捕获写入异常，避免因流关闭/已提交导致的崩溃
                log.debug(String.valueOf("响应已提交，跳过重复写入：" + Request.getRequestURI()));
                throw new IOException("写入响应流失败：" + e.getMessage(), e);
            }
        }
    }

    private String getDomainFromUrl(String url) {
        try {
            URL urlObj = new URL(url);
            return urlObj.getProtocol() + "://" + urlObj.getAuthority();
        } catch (Exception e) {
            return "";
        }
    }

    /**
     * 初始化系统参数
     */
    protected void initSystemParams(HttpServletRequest ctx) {
        try {
            ctx.setCharacterEncoding("UTF-8");
            this.Request = ctx;
            this.Response = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
            this.Response.setContentType("text/plain");
            // 从 ctx 重新获取 Session，避免依赖 this.Session 字段
//            HttpSession session = ctx.getSession(false); // 注意：false 表示不创建新 Session
//            // 用户信息初始化
//            _user = (LoginUserInfo) session.getAttribute(getUserSessionName());
//            if (getUser() == null) {
//                String userId = getBImpl().Request("userid");
//                String userName = getBImpl().Request("username");
//                if (!isNullOrEmpty(userId) && !isNullOrEmpty(userName)) {
//                    _user = new LoginUserInfo();
//                    getUser().UserId = (userId);
//                    getUser().UserName = (userName);
//                    session.setAttribute(getUserSessionName(), getUser());
//                }
//            }
        } catch (Exception e) {
            LoggerHandler.error("inierror", e);
        }
    }

    /**
     * 返回给客户端登录的指令
     */
    protected void goLogin() throws IOException {
        String authorization = context == null ? "" : context.getHeader("Authorization");
        // 2. 统一将 null 转换为空字符串，避免后续调用方法时报错
        authorization = (authorization == null) ? "" : authorization;
        if (!isNullOrEmpty(authorization) && authorization.startsWith("Bearer ")) {
//            log("登录失效：" + authorization);
        }

        response.setSuccess(false);
        response.setMsg("response_login");
        writeResponse();
    }

    /**
     * 重定向到指定页面
     */
    protected void redirect(String url, Object data) {
        response.setSuccess(false);
        response.setMsg("response_redirect");
        Map<String, Object> redirectData = new HashMap<>();
        redirectData.put("url", url);
        redirectData.put("data", data);
        response.setData(redirectData);
    }

    /**
     * 向页面输送脚本
     */
    protected void registerScript(String script, Object data) {
        response.setSuccess(false);
        response.setMsg("response_RegisterScript");
        Map<String, Object> scriptData = new HashMap<>();
        scriptData.put("script", script);
        scriptData.put("data", data);
        response.setData(scriptData);
    }

    /**
     * 检查参数是否为空，被RequestCheck类替代
     */
    protected boolean checkParam(String paramname, Object paramval) {
        boolean ok = true;
        if (paramval instanceof Integer) {
            if ((Integer) paramval == 0) {
                ok = false;
            }
        } else if (paramval == null || isNullOrEmpty(paramval.toString())) {
            ok = false;
        }

        if (!ok) {
            response.setSuccess(false);
            response.setMsg(String.format("%s:%s", LanguageUtil.GetString("InvalidParameter"), paramname));
        }
        return ok;
    }

    /**
     * 检查登录状态
     */
//    @RequestCheck(CheckLogin = false)
    public boolean checkLogin() {
        return checkLoginByPro();
    }

    protected boolean checkLoginByPro() {
        boolean isLoggedIn = getUser() != null && !"0".equals(getUser().UserId);
//        out.println("isLoggedIn: " + isLoggedIn + getUser().UserName);
        response.setSuccess(isLoggedIn);
        response.setData(isLoggedIn ? getUser() : null);
        response.setSharToken(toBoolean(WebConfigUtil_web.get("SharLogin", "1")));

        if (ToInt32(WebConfigUtil.get("MsgBtnOrder", "0")) == 1) {
            response.AppCfg = new HashMap<>();
            response.AppCfg.put("MsgBtnOrder", 1);
        }
        if (isLoggedIn && "CheckLogin".equals(methodName)) {
            if (SingleUserHandler.hasUnLoginUser(getSessionId()) ||
                    (!SingleUserHandler.hasSessionUser(getSessionId()) && SingleUserHandler.hasLoginUser(getUser().UserId))) {
                loginOut();
                response.setSuccess(false);
                response.setData(null);
            } else {
                SingleUserHandler.add(getSessionId(), getUser().UserId);
            }

            if (response.isSuccess() && isDefaultPwd(getUser().Pwd) && toBoolean(WebConfigUtil_web.get("RestInitPwd", ""))) {
                response.setMsg("请修改密码！");
                response.setOther(LoginCode.ResetPwd);
            }

            if (isNullOrEmpty(getUser().Token) && !toBoolean(WebConfigUtil_web.get("SharLogin", "1"))) {
                response.setToken(JwtHelp.createToken(getUser(), 7200));
            }
        }
//        out.println("返回的正否" + response.isSuccess());
        return response.isSuccess();
    }

    protected boolean isDefaultPwd(String pwd) {
        return "51B4FCEDBC944C6F5627E732CD9560B8B1204FDB".equals(pwd) ||
                "E0B97F132980BB0856ECC51BA256626F3CB68D11".equals(pwd) ||
                "A839A93FD1A6699CAA208BB1DB9E2D25A7013E86".equals(pwd);
    }

    //    @RequestCheckAttribute(log = false)
    public void loginOut() {
        int delay = parseInt(getBImpl().Request("delay"));
        String userId = "", sessionId = getSessionId();

        if (getUser() == null) {
            return;
        }
        userId = getUser().UserId;
//        out.println(userId + "userid:" + sessionId);
        if (delay > 0) {
            SingleUserHandler.waitLoginOut(sessionId);
            DateTimeUtil.setTimeOut(() -> {
                if (SingleUserHandler.hasWaitUnLoginUser(sessionId)) {
                    SingleUserHandler.unLogin(sessionId);
                }
            }, delay * 1000);
        } else {
            Session.removeAttribute(getUserSessionName());
            SingleUserHandler.remove(sessionId);
            JwtHelp.removeUserCache(getUser());
            CacheUtil.remove(getUser().Token);
            CacheUtil.clearUserCache(getUser().UserName, getUser().UserId);

            if (getBImpl().isPhone()) {
                response.setOther(0);
            }
        }

        response.setData(null);
        response.setSuccess(true);
    }

    public void unLoginOut() {
        SingleUserHandler.unLogin(getSessionId());
        response.setSuccess(true);
    }

    /**
     * 清除服务器缓存
     */
//    @RequestCheckAttribute(checkLogin = false)
    public void clearCache() {
        CacheUtil.clearCache();
        response.setSuccess(true);
    }

    /**
     * 获取活跃用户
     */
//    @RequestCheckAttribute(checkLogin = true)
    public void getActiveUser() {
        Object[] users = ActiveUserUtil.getActiveUser();
        response.setTot(users == null ? 0 : users.length);
        response.setData(users);
        response.setSuccess(true);
    }

    /**
     * 获取平均请求数
     */
//    @RequestCheckAttribute(checkLogin = true)
    public void getAvgRequest() {
        boolean reset = toBoolean(getBImpl().Request("reset"));
        int mins = Math.max((int) Duration.between((Temporal) startDate, LocalDateTime.now()).toMinutes(), 1);


        Date StartDate = Date.from(
                startDate.atZone(ZoneId.systemDefault()) // 绑定系统默认时区
                        .toInstant() // 转换为 Instant
        );

        LocalDateTime now = LocalDateTime.now();
        Date nowDate = Date.from(now.atZone(ZoneId.systemDefault()).toInstant());
        Map<String, Object> data = new Hashtable<>();
        data.put("tot", requestCount);
        data.put("start", startDate);
        data.put("avg", requestCount / Math.max(1, mins));
        data.put("maxps", maxPMins);
        data.put("maxPDate", maxPDate.format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
        data.put("mins", mins);
        data.put("runed", DateTimeUtil.getDateDiff(StartDate, nowDate));

        response.setData(data);
        response.setSuccess(true);

        if (reset) {
            resetPCount();
        }
    }

    //    @RequestCheckAttribute(checkLogin = false)
    public void getDate() {
        response.setSuccess(true);
        response.setData(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
    }

    private void resetPCount() {
        startDate = LocalDateTime.now();
        requestCount = 0;
        maxPMins = 0;
        lastMins = 0;
    }

    public boolean isReusable() {
        return toBoolean(WebConfigUtil_web.get("ReusaHandler", "1"));
    }

}
