package com.cpop.oam.business.service.impl;

import com.cpop.core.base.exception.ServiceException;
import com.cpop.core.base.table.Config;
import com.cpop.core.service.ConfigService;
import com.cpop.core.service.RedisService;
import com.cpop.core.utils.SpringUtils;
import com.cpop.core.utils.StringUtils;
import com.cpop.core.utils.bean.BeanUtils;
import com.cpop.oam.business.bo.SysConfigInfoBo;
import com.cpop.oam.business.service.CommonService;
import com.cpop.oam.business.vo.ConfigInfoVo;
import com.cpop.oam.framework.constant.OamConfigKey;
import com.cpop.oam.framework.enums.OamConfigEnum;
import com.mybatisflex.core.row.DbChain;
import jakarta.annotation.PostConstruct;
import org.springframework.stereotype.Service;

import java.lang.reflect.Field;
import java.util.*;

import static com.cpop.core.base.table.table.ConfigTableDef.CONFIG;


/**
 * @author DB
 * @since 2023/09/13 12:45
 */
@Service("oamCommonService")
public class CommonServiceImpl implements CommonService {

    /**
     * 项目启动时，初始化参数到缓存
     */
    @PostConstruct
    private void init() {
        loadingConfigCache();
    }

    /**
     * 加载参数缓存数据
     */
    @Override
    public void loadingConfigCache() {
        List<String> keys = new ArrayList<>(Arrays.asList(OamConfigKey.WORK_WX_INFO));
        List<String> demandToTask = Arrays.asList(OamConfigKey.DEMAND_TO_TASK);
        keys.addAll(demandToTask);
        List<String> signGoalList = Arrays.asList(OamConfigKey.SIGN_GOAL);
        keys.addAll(signGoalList);
        // 加载OAM配置参数
        List<Config> configsList = DbChain.table(CONFIG)
            .select(CONFIG.ALL_COLUMNS)
            .where(CONFIG.CONFIG_KEY.in(keys))
            .listAs(Config.class);
        if (!configsList.isEmpty()) {
            for (Config config : configsList) {
                SpringUtils.getBean(RedisService.class)
                    .setCacheObject(getCacheKey(config.getConfigKey()), config.getConfigValue());
            }
        }
    }

    /**
     * 重置参数缓存数据
     */
    @Override
    public void resetConfigCache() {
        clearConfigCache();
        loadingConfigCache();
    }

    /**
     * 清空参数缓存数据
     */
    @Override
    public void clearConfigCache() {
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        Collection<String> keys = redisService.keys(OamConfigKey.OAM_CONFIG_KEY + "*");
        redisService.deleteObject(keys);
    }

    /**
     * 设置cache key
     *
     * @param configKey 参数键
     * @return 缓存键key
     */
    @Override
    public String getCacheKey(String configKey) {
        return OamConfigKey.OAM_CONFIG_KEY + configKey;
    }

    /**
     * 获取系统配置信息
     * @return R<OpenPlatformConfigVo>
     * @author DB
     * @since 2023/7/7 0007 16:27
     */
    @Override
    public ConfigInfoVo getSysConfigInfo() {
        RedisService redisService = SpringUtils.getBean(RedisService.class);
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        // 获取企业微信信息
        Map<String, String> configMap = new HashMap<>(8);
        Arrays.asList(OamConfigKey.WORK_WX_INFO).forEach(item -> {
            String cacheInfo = redisService.getCacheObject(getCacheKey(item));
            if (StringUtils.isNotBlank(cacheInfo)) {
                // 获取枚举
                OamConfigEnum sysConfigEnum = OamConfigEnum.matchKey(item);
                configMap.put(sysConfigEnum.getField(), cacheInfo);
            } else {
                // 查询系统
                Config sysConfig = configService.getById(item);
                if (null != sysConfig) {
                    // 获取枚举
                    OamConfigEnum sysConfigEnum = OamConfigEnum.matchKey(item);
                    configMap.put(sysConfigEnum.getField(), sysConfig.getConfigValue());
                }
            }
        });
        ConfigInfoVo sysConfigInfoVo = new ConfigInfoVo();
        BeanUtils.mapToObj(configMap, sysConfigInfoVo);
        return sysConfigInfoVo;
    }

    /**
     * @param bo 请求参数
     * 设置系统配置信息
     * @author DB
     * @since 2023/5/11 15:48
     **/
    @Override
    public void setSysConfigInfo(SysConfigInfoBo bo) {
        ConfigService configService = SpringUtils.getBean(ConfigService.class);
        // 遍历属性名与值
        try {
            for (Field field : bo.getClass().getDeclaredFields()) {
                field.setAccessible(true);
                // 获取枚举
                OamConfigEnum sysConfigEnum = OamConfigEnum.matchField(field.getName());
                if (null != sysConfigEnum) {
                    Config sysConfig = new Config();
                    sysConfig.setConfigName(sysConfigEnum.getName())
                        .setConfigKey(sysConfigEnum.getKey())
                        .setConfigValue(field.get(bo).toString());
                    // 修改
                    if (DbChain.table(CONFIG)
                        .where(CONFIG.CONFIG_KEY.eq(sysConfig.getConfigKey()))
                        .count() > 0) {
                        configService.updateById(sysConfig);
                    } else {
                        configService.save(sysConfig);
                    }
                    // 更新缓存
                    SpringUtils.getBean(RedisService.class)
                        .setCacheObject(getCacheKey(sysConfigEnum.getKey()), sysConfig.getConfigValue());
                }
            }
        } catch (IllegalAccessException e) {
            throw new ServiceException("更新系统配置失败,请联系相关人员!");
        }
    }
}
