package org.example.Impl;
/**
 * 功能描述：BaseImpl 所有逻辑业务类的基础类
 */

import com.fasterxml.jackson.databind.ObjectMapper;
import jakarta.servlet.http.HttpServletRequest;
import org.example.Api.RequestHandler;
import org.example.Entity.System.LoginUserInfo;
import org.example.Enums.SystemTypeEnums;
import org.example.Impl.Sql.factory.AllInOneSqlFactory;
import org.example.Impl.Sql.provider.AllInOneSqlProvider;
import org.example.ModuleApi.ModuleAjaxApi.mapper.CRMapper;
import org.example.ModuleApi.ModuleAjaxApi.mapper.DMCrmMapper;
import org.example.Utils.ConfigUtil;
import org.example.Utils.DbOperator;
import org.example.Utils.WebConfigUtil_web;
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.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Map;

import jakarta.servlet.http.HttpSession; // Jakarta EE 9+ 版本（如Spring Boot 3+）
import org.example.Utils.JwtHelp;

import static org.example.Utils.NativeExtensionUtils.isNullOrEmpty;
import static org.example.Utils.NativeExtensionUtils.toBoolean;

@Service
public class BaseImpl {

    @Autowired
    protected JdbcTemplate jdbcTemplate;


    @Value("${custom.database.type}")
    protected String databaseType;


    @Autowired
    AllInOneSqlFactory allInOneSqlFactory;

    @Autowired
    protected CRMapper crmapper;

    @Autowired
    protected DMCrmMapper DMCrmMapper;




    public HttpServletRequest getCtx() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        return attributes != null ? attributes.getRequest() : null;
    }

    @Autowired
    private DbOperator dbOperator;
    public boolean alwaysNewDbOper = false;

    /**
     * 数据库操作对象
     */
    public DbOperator getDbOperator() {
        if (dbOperator == null || alwaysNewDbOper) {
            dbOperator = getNewOperater();
            return dbOperator;
        }
        return dbOperator;
    }

    public void setDbOperator(DbOperator dbOperator) {
        this.dbOperator = dbOperator;
    }

    public DbOperator getOperater() {
        return getDbOperator();
    }

    public DbOperator getNewOperater() {
        return new DbOperator(jdbcTemplate);
    }

    private String connectionString;

    /**
     * 账套链接字符串
     */
    protected String getConnectionString() {
        if (isNullOrEmpty(connectionString) && user != null && !"0".equals(user.UserId)
                && !isNullOrEmpty(user.ConnectionString)) {
            connectionString = user.ConnectionString;
        }
        return connectionString;
    }

    protected String providerName;

    public String getProviderName() {
        return providerName;
    }

    public void setProviderName(String providerName) {
        this.providerName = providerName;
    }

    /**
     * 核心：根据 providerName 映射 JDBC 驱动类名（支持主流数据库）
     * 示例：providerName="sqlserver" → 驱动类=com.microsoft.sqlserver.jdbc.SQLServerDriver
     */
    protected String getJdbcDriverByProvider() {
        getLog().debug(String.valueOf("getJdbcDriverByProvider正式进入"));
        getLog().debug(String.valueOf("正式进入"+ConfigUtil.getProviderName()));
        // 先校验 providerName 是否已通过 setter 初始化
        if (ConfigUtil.getProviderName() == null ||ConfigUtil.getProviderName().trim().isEmpty()) {
            getLog().debug(String.valueOf("进入抛出错误"));
            throw new RuntimeException("providerName 未初始化，请先调用 setProviderName 方法设置！");
        }
        // 映射关系（可根据你的实际数据库扩展，比如mysql、oracle）
        Map<String, String> driverMap = new HashMap<>();
        driverMap.put("sqlserver", "com.microsoft.sqlserver.jdbc.SQLServerDriver"); // SQL Server
        driverMap.put("mysql", "com.mysql.cj.jdbc.Driver"); // MySQL 8.0+
        driverMap.put("oracle", "oracle.jdbc.driver.OracleDriver"); // Oracle
        driverMap.put("dm", "dm.jdbc.driver.DmDriver");
        driverMap.put("kingbase", "com.kingbase8.Driver");
        getLog().debug(String.valueOf("getJdbcDriverByProvider内部通过0"));
        // 1. 优先用完整的 providerName 匹配（如果直接传入驱动类名）
        if (ConfigUtil.getProviderName() != null && ConfigUtil.getProviderName().contains(".")) {
            getLog().debug(String.valueOf("getJdbcDriverByProvider内部通过1"));
            return ConfigUtil.getProviderName();
        }
        getLog().debug(String.valueOf("当前providerName值：" + ConfigUtil.getProviderName() + "，转小写后：" + (ConfigUtil.getProviderName() != null ? ConfigUtil.getProviderName().toLowerCase() : "null")));
        // 2. 用简写匹配（如 "sqlserver"）
        String driverClass = driverMap.getOrDefault(ConfigUtil.getProviderName().toLowerCase(), null);
        getLog().debug(String.valueOf("getJbdc内部通过2"));
        if (driverClass == null) {
            throw new RuntimeException("未找到 providerName 对应的 JDBC 驱动！providerName=" +ConfigUtil.getProviderName());
        }
        return driverClass;
    }


    private Boolean windowsDirver;

    public boolean isWindowsDirver() {
        if (windowsDirver == null) {
            HttpServletRequest ctx = getCtx();
            windowsDirver = (ctx != null) ? toBoolean(Request("windowsDirver", "1")) : true;
        }
        return windowsDirver;
    }

    public void setWindowsDirver(boolean windowsDirver) {
        this.windowsDirver = windowsDirver;
    }

    private Integer currPage;

    public int getCurrPage() {
//        if (currPage == null) {
        HttpServletRequest ctx = getCtx();
        currPage = (ctx == null) ? 1 : toInt32(Request("currPage", Request("page", "1")));
//        }
        return currPage;
    }

    public void setCurrPage(int currPage) {
        this.currPage = currPage;
    }

    private Integer pageSize;

    public int getPageSize() {
//        if (pageSize == null) {
        HttpServletRequest ctx = getCtx();
        pageSize = (ctx == null) ? 1 : toInt32(Request("pageSize", Request("limit", "-1")));
//        }
        return pageSize;
    }

    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }

    public int getStartsize() {
        int start = (getCurrPage() - 1) * getPageSize();
        return Math.max(start, 0);
    }

    protected int tot = 0;

    private String userSessionName;

    public String getUserSessionName() {
        userSessionName = WebConfigUtil_web.Session_LoginUser;
        if (isNullOrEmpty(getAppName())) {
            userSessionName = getAppName() + "_" + WebConfigUtil_web.Session_LoginUser;
        }
        return userSessionName;
    }

    private String sessionId;

    public String getSessionId() {
        HttpServletRequest ctx = getCtx();
        if (ctx == null || ctx.getSession() == null) {
            return "";
        }
        if (!isNullOrEmpty(getAppName())) {
            sessionId = getAppName() + "_" + ctx.getSession().getId();
        }
        return sessionId;
    }

    /**
     * 附件路径
     */
    public String getAttcPath() {
        return WebConfigUtil_web.getFilePath();
    }

    private LoginUserInfo user;

    public LoginUserInfo getUser() {
        if (user == null) {
            user = new LoginUserInfo();
        }
        HttpServletRequest ctx = getCtx();
        if (ctx == null) {
            return user;
        }

        // 优先使用session验证
        if (getCurrentUser().UserId != "0" && toBoolean(WebConfigUtil_web.get("SharLogin", "1"))
                && !isNullOrEmpty(getCurrentUser().ConnectionString)) {
            user = getCurrentUser();
        }
        if (user == null || "0".equals(user.UserId)) {
            try {
                // 检查请求上下文是否可用
                ctx.getRequestURI();
            } catch (Exception e) {
                getLog().debug(String.valueOf(e.getMessage()));
                return user;
            }

            String authorization = ctx.getHeader("Authorization");
            authorization = (authorization == null) ? "" : authorization;
            if (!isNullOrEmpty(authorization) && authorization.startsWith("Bearer ")) {
                user = JwtHelp.validToken(authorization.substring("Bearer ".length()), LoginUserInfo.class);
            }
        }

        return user != null ? user : new LoginUserInfo();
    }

    public void setUser(LoginUserInfo user) {
        this.user = user;
    }

    private Logger log;

    /**
     * 日志操作对象
     */
    protected Logger getLog() {
        if (log == null) {
            log = LoggerFactory.getLogger(this.getClass());
        }
        return log;
    }

    public void sysLog(String content, String type) {
        getLog().info(content);
    }

    public String getLanguage() {
        HttpServletRequest ctx = getCtx();
        if (ctx != null) {
            String lang = Request("lg", "CN");
            return (lang).toUpperCase();
        }
        return "CN";
    }

    /**
     * 获取会话值
     */
    public static Object getSessionVal(String name) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpSession session = attributes.getRequest().getSession(false);
            if (session != null) {
                return session.getAttribute(name);
            }
        }
        return null;
    }

    /**
     * 设置会话值
     */
    public static void setSessionVal(String name, Object value) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            HttpSession session = attributes.getRequest().getSession();
            if (session != null) {
                session.setAttribute(name, value);
            }
        }
    }

    public LoginUserInfo getCurrentUser() {
        Object userObj = getSessionVal(getUserSessionName());
        if (userObj instanceof LoginUserInfo) {
            return (LoginUserInfo) userObj;
        }
        return new LoginUserInfo() {{
            UserId = ("0");
        }};
    }

    /**
     * 超级管理员
     */
    public String userManager = "管理员";

    public boolean isUserManager() {
        return userManager.equals(getUser().UserName);
    }

    public String getAppUrl() {
        return WebConfigUtil_web.get("appUrl", "");
    }

    private String appName;

    public String getAppName() {
        if (isNullOrEmpty(appName)) {
            appName = Request("sysAppName");
        }
        if (isNullOrEmpty(appName)) {
            appName = "Lserp_v8";
        }
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    private String driverUuId;

    public String getDriverUuId() {
        if (driverUuId == null) {
            driverUuId = Request("uuid");
        }
        return driverUuId;
    }

    private String driver;

    public String getDriver() {
        if (driver == null) {
            driver = (Request("driver") + "").toLowerCase();
        }
        return driver;
    }

    private String osModel;

    public String getOsModel() {
        if (isNullOrEmpty(osModel)) {
            osModel = (Request("OsModel") + "").toLowerCase();
            if (isNullOrEmpty(osModel)) {
                osModel = isWindowsDirver() ? "web" : "mobileweb";
            }
        }
        return osModel;
    }

    private String appDomain;

    public String getAppDomain() throws UnsupportedEncodingException {
        if (appDomain == null) {
            appDomain = java.net.URLDecoder.decode(Request("appDomain"), StandardCharsets.UTF_8);
        }
        return appDomain;
    }

    /**
     * 是否为移动设备
     */
    public boolean isPhone() {
        String driver = getDriver();
        return !isNullOrEmpty(driver) && ("ios".equals(driver) || "android".equals(driver));
    }

    private int appVersion;

    public int getAppVersion() {
        if (appVersion <= 0) {
            appVersion = toInt32(Request("appVer", "0"));
        }
        return appVersion;
    }

    public static String getAppPhysicsPath() {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        if (attributes != null) {
            return attributes.getRequest().getServletContext().getRealPath("/");
        }
        return "";
    }

    public SystemTypeEnums.LoginType getLgType() {
        return getReqHandler().getLgType();
    }

    //region 接收参数相关

    private RequestHandler reqHandler;

    public RequestHandler getReqHandler() {
        if (reqHandler == null) {
            reqHandler = new RequestHandler();
        }
        return reqHandler;
    }

    public void setReqHandler(RequestHandler reqHandler) {
        this.reqHandler = reqHandler;
    }

    /**
     * 获取表单参数
     */
    public String Request(String key, String defaultVal) {
        return getReqHandler().request(key, defaultVal);
    }

    public String Request(String key) {
        return Request(key, "");
    }

    public String PmsRequest(String key, String defaultVal) {
        return getReqHandler().pmsRequest(key, defaultVal);
    }

    public Hashtable<String, String> getAllRequest() {
        Hashtable<String, String> params = new Hashtable<>();
        HttpServletRequest request = getCtx();
        if (request != null) {
            Enumeration<String> paramNames = request.getParameterNames();
            while (paramNames.hasMoreElements()) {
                String key = paramNames.nextElement();
                params.put(key, request.getParameter(key));
            }
        }
        return params;
    }


    // 工具方法：字符串转整数
    protected int toInt32(String value) {
        return toInt32(value, 0);
    }

    protected int toInt32(String value, int defaultValue) {
        if (value == null || value.trim().isEmpty()) {
            return defaultValue;
        }
        try {
            return Integer.parseInt(value.trim());
        } catch (NumberFormatException e) {
            return defaultValue;
        }
    }
}
