package org.example.Impl;

import org.example.Entity.BaseResponse.BaseResponse;
import org.example.Entity.System.LoginUserInfo;
import org.example.Impl.Sql.factory.AllInOneSqlFactory;
import org.example.ModuleApi.ModuleAjaxApi.mapper.CRMapper;
import org.example.ModuleApi.ModuleAjaxApi.mapper.DMCrmMapper;
import org.example.Utils.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.jdbc.core.JdbcTemplate;

import java.io.UnsupportedEncodingException;
import java.util.Objects;

/**
 * 功能描述：OptBaseImpl 操作类的父类
 */
public class OptBaseImpl extends BaseImpl {

    public OptBaseImpl(JdbcTemplate dbOperator, String databaseType,
                       AllInOneSqlFactory allInOneSqlFactory, CRMapper crmapper, DMCrmMapper DMCrmMapper) {
        this.jdbcTemplate = dbOperator;
        this.databaseType = databaseType;
        this.allInOneSqlFactory = allInOneSqlFactory;
        this.crmapper = crmapper;
        this.DMCrmMapper = DMCrmMapper;
    }

    protected static final Logger log = LoggerFactory.getLogger(OptBaseImpl.class);

    private IPublicUtil util;

    public OptBaseImpl() {

    }

    public synchronized IPublicUtil getUtil() {
        if (util == null) {
            util = new IPublicUtil(jdbcTemplate);
            util.setReqHandler(getReqHandler());
            util.setDbOperator(getDbOperator());
        }
        return util;
    }


    private DataImpl dataImpl;

    protected synchronized DataImpl getDataImpl() {
        if (dataImpl == null) {
//            dataImpl = new DataImpl(getDbOperator());
            dataImpl = new DataImpl(jdbcTemplate, databaseType, allInOneSqlFactory, crmapper, DMCrmMapper);
        }
        return dataImpl;
    }

    protected void setDataImpl(DataImpl dataImpl) {
        this.dataImpl = dataImpl;
    }

    private DbOperator oldDbOperator;

    public DbOperator getOldDbOperator() {
        return oldDbOperator;
    }

    public void setOldDbOperator(DbOperator oldDbOperator) {
        this.oldDbOperator = oldDbOperator;
    }

    @Autowired
    private DbOperator dbOperator;

    @Override
    public DbOperator getDbOperator() {
        if (dbOperator != null) {
            return dbOperator;
        }

        DbOperator baseDbOper = super.getDbOperator();
        int serverId = getServerId();
        LoginUserInfo currentUser = getUser();

        if (serverId > 0 && (currentUser == null || currentUser.ServerId != serverId)) {
            oldDbOperator = baseDbOper;
            SysUserImpl userImpl = new SysUserImpl(SpringContextHolder.getDataImpl());
            userImpl.setDbOperator(baseDbOper);
            StringBuilder errMsg = new StringBuilder();
            DbOperator serverDbOper = userImpl.getServerDbOper(serverId, errMsg);
            dbOperator = Objects.requireNonNullElse(serverDbOper, baseDbOper);
        } else {
            dbOperator = baseDbOper;
        }

        return dbOperator;
    }

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

    private Integer serverId;

    public int getServerId() {
        if (serverId == null) {
            serverId = (getCtx() == null) ? 0 : NativeExtensionUtils.ToInt32(Request("serverId", "0"));
        }
        return serverId;
    }

    public void setServerId(int serverId) {
        this.serverId = serverId;
    }

    private SysUserImpl userImpl;

    @Override
    public LoginUserInfo getUser() {

        LoginUserInfo user = super.getUser();
        if (user != null && !"0".equals(user.UserId) && user.ConnectionString == null) {
            String token = user.Token;
            SysUserImpl userImpl = new SysUserImpl(SpringContextHolder.getDataImpl());

            userImpl.setJdbcTemplate(jdbcTemplate);
            DbOperator dbOper = new DbOperator(jdbcTemplate);
            userImpl.setDbOperator(dbOper);
            if (user.ServerId > 0) {
                StringBuilder errMsg = new StringBuilder();
                dbOper = userImpl.ChangeServer(user.ServerId, errMsg);
            } else {
                dbOper = new DbOperator(jdbcTemplate);
            }

            if (dbOper != null) {
                BaseResponse res = new BaseResponse();
                user = userImpl.OnLoginSuccess(
                        null, user, user.SeriesId, user.ServerId,
                        user.UserId, dbOper.getConnectionString(), res, true
                );
                user.Token = (token);
                user.LoginOs = (getOsModel());
                user.ConnectionString = (dbOper.getConnectionString());
            }

            super.setUser(user);
            JwtHelp.setUserCache(user, isWindowsDirver() ? 7200 : 2592000);
            setSessionVal(getUserSessionName(), user);
        }
        return user;
    }

    @Override
    public void setUser(LoginUserInfo user) {
        super.setUser(user);
    }

    private String moduleCode;

    protected String getModuleCode() {
        if (moduleCode == null && getCtx() != null) {
            moduleCode = Request("ModuleId", Request("menucode", ""));
        }
        return moduleCode;
    }

    protected void setModuleCode(String moduleCode) {
        this.moduleCode = moduleCode;
    }

    private String menuId;

    protected String getMenuId() {
        if (menuId == null && getCtx() != null) {
            menuId = Request("MenuId", "");
        }
        return menuId;
    }

    protected String getOAUrl() {
        return getDataImpl().GetSystemOAUrl();
    }

    private boolean isUseDbAttc() {
        return NativeExtensionUtils.toBoolean(WebConfigUtil_web.get("useDbAttc", ""));
    }

    @Override
    public String getAttcPath() {
        if (!isUseDbAttc() || getDataImpl().isDefaultServer()) {
            return WebConfigUtil_web.getFilePath();
        }
        return getDataImpl().GetSystemAttcPath();
    }

    @Override
    public String getAppDomain() throws UnsupportedEncodingException {
        if (!getDataImpl().isDefaultServer() && isUseDbAttc()) {
            return getOAUrl();
        }
        return super.getAppDomain();
    }

    @Override
    public void sysLog(String content, String type) {
        log.info(content);
        try {
//            SystemLog.setDbOperator(new DbOperator(jdbcTemplate));
//            SystemLog.info(content, getUser(), getLgType(), null, null, getModuleCode(), type);
        } catch (Exception ex) {
            log.error("日志写入错误: " + ex.getMessage(), ex);
        }
    }
}
