package com.mortals.xhx.base.system.param.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mortals.framework.common.code.YesNo;
import com.mortals.framework.exception.AppException;
import com.mortals.framework.model.Context;
import com.mortals.framework.service.IParam;
import com.mortals.framework.service.impl.AbstractCRUDCacheServiceImpl;
import com.mortals.framework.util.StringUtils;
import com.mortals.xhx.base.system.param.dao.ParamDao;
import com.mortals.xhx.base.system.param.model.ParamEntity;
import com.mortals.xhx.base.system.param.model.ParamQuery;
import com.mortals.xhx.base.system.param.service.ParamService;

import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>Title: 参数信息</p>
 * <p>Description: ParamServiceImpl service接口 </p>
 * <p>Copyright: Copyright &reg;  </p>
 * <p>Company: </p>
 *
 * @author
 * @version 1.0.0
 */
@Service("paramService")
public class ParamServiceImpl extends AbstractCRUDCacheServiceImpl<ParamDao, ParamEntity, Long>
        implements ParamService {

    @Override
    protected String getExtKey(ParamEntity data) {
        return data.getParamKey();
    }

    @Override
    protected String getCacheName() {
        return "ParamEntity.paramKey";
    }

    @Override
    public void putCache(String key, ParamEntity data) {
        cacheService.set(data.getParamKey(), data.getParamValue());
    }

    @Override
    public void removeCache(String key) {
    }

    @Override
    public int remove(Long[] ids, Context context) throws AppException {
        // 先删缓存
        for (Long id : ids) {
            ParamEntity paramEntity = get(id, null);
            cacheService.del(paramEntity.getParamKey());
        }
        removeBefore(ids, context);
        int iRet = dao.delete(ids);
        removeAfter(ids, context, iRet);
        return iRet;
    }

    @Override
    public String getValueByKey(String key) {
        return cacheService.get(key);
    }

    @Override
    public Map<String, String> getParamByFirstOrganize(String firstOrganize, String... excludeParamKeys) {
        ParamQuery query = new ParamQuery();
        query.setFirstOrganize(firstOrganize);
        List<ParamEntity> list = this.getDao().getList(query);
        return list.stream().filter(s -> {
            return !Arrays.asList(excludeParamKeys).contains(s.getParamKey());
        }).collect(Collectors.toMap(ParamEntity::getParamKey, ParamEntity::getParamValue));
    }

    public Map<String, String> getParamBySecondOrganize(String firstOrganize, String secondOrganize, String... excludeParamKeys) {
        ParamQuery query = new ParamQuery();
        query.setFirstOrganize(firstOrganize);
        query.setSecondOrganize(secondOrganize);
        List<ParamEntity> list = this.getDao().getList(query);
        return list.stream().filter(s -> {
            return !Arrays.asList(excludeParamKeys).contains(s.getParamKey());
        }).collect(Collectors.toMap(ParamEntity::getParamKey, ParamEntity::getParamValue));
    }


    @Override
    public boolean needRefresh() {
        if (super.cacheService.isShareCache())//共享缓存，不需要实时刷新
        {
            return false;
        }
        IParam param = this.findByKey(IParam.KEY_PARAM_REFRESH_COUNT);
        if (param != null) {
            String value = StringUtils.trim(param.getParamValue());
            IParam memParam = getParamByKey(IParam.KEY_PARAM_REFRESH_COUNT);
            if (memParam == null || !value.equals(StringUtils.trim(memParam.getParamValue()))) {
                return true;
            }
        }
        return false;
    }

    @Override
    public void refresh() {
        log.info("开始初始化系统参数...");
        try {
            super.removeAllCache();
            super.loadCache();
            log.info("系统参数初始化完成！");
        } catch (Exception e) {
            log.error("查询系统参数异常", e);
        }
    }

    @Override
    public IParam findByKey(String key) throws AppException {
        ParamQuery params = new ParamQuery();
        params.setValidStatus(YesNo.YES.getValue());
        params.setParamKey(key);
        List<ParamEntity> list = super.find(params, null);
        if (list != null && !list.isEmpty()) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public List<? extends IParam> findAll() throws AppException {
        ParamQuery params = new ParamQuery();
        params.setValidStatus(YesNo.YES.getValue());
        return super.find(params, null);
    }

    @Override
    public boolean containsParamKey(String key) {
        return cacheService.hget(getCacheName(), key) != null;
    }

    @Override
    public IParam getParamByKey(String key) {
        return getExtCache(key);
    }

    @Override
    public String getParamValue(String key) {
        String hget = cacheService.hget(getCacheName(), key);

        if (StringUtils.isEmpty(hget))return "";

        IParam param = wrapParamObject(hget);
//        IParam param = getExtCache(key);
        if (param != null) {
            return StringUtils.trim(param.getParamValue());
        }
        return "";
    }

    private IParam wrapParamObject(String entityString) {
        JSONObject jsonObject = JSON.parseObject(entityString);
        ParamEntity param = new ParamEntity();
        param.setCreateTime(jsonObject.getDate("createTime"));
        param.setCreateUserId(jsonObject.getLong("createUserId"));
        param.setDisplayType(jsonObject.getInteger("displayType"));
        param.setFirstOrganize(jsonObject.getString("firstOrganize"));
        param.setId(jsonObject.getLong("id"));
        param.setModStatus(jsonObject.getInteger("modStatus"));
        param.setName(jsonObject.getString("name"));
        param.setParamKey(jsonObject.getString("paramKey"));
        param.setParamValue(jsonObject.getString("paramValue"));
        param.setValidStatus(jsonObject.getInteger("validStatus"));

        return param;
    }

    @Override
    public String getParamValue(String key, String defaultValue) {
        if (containsParamKey(key)) {
            String value = getParamValue(key);
            if (StringUtils.isEmpty(value)) {
                return defaultValue;
            }
            return value;
        } else {
            log.debug("cannot found key[" + key + "], use default value[" + defaultValue + "]");
            return defaultValue;
        }
    }

    @Override
    public int getParamIntValue(String key) {
        ParamEntity extCache = getExtCache(key);
        IParam param =  extCache;
        try {
            if (param == null) {
                return 0;
            }
            String value = param.getParamValue();
            if (StringUtils.isEmpty(value)) {
                return 0;
            } else {
                return Integer.parseInt(value);
            }
        } catch (Exception e) {
            return 0;
        }
    }

    @Override
    public int getParamIntValue(String key, int defaultValue) {
        if (containsParamKey(key)) {
            String value = getParamValue(key);
            if (StringUtils.isEmpty(value)) {
                return defaultValue;
            }
            try {
                return Integer.parseInt(value);
            } catch (Exception e) {
                log.debug("cannot conver key[" + key + "]'s value[" + value + "] to int, use default value[" + defaultValue + "]");
                return defaultValue;
            }
        } else {
            log.debug("cannot found key[" + key + "], use default value[" + defaultValue + "]");
            return defaultValue;
        }
    }

    @Override
    public long getParamLongValue(String key) {
        IParam param = getExtCache(key);
        try {
            if (param == null) {
                return 0;
            }
            String value = param.getParamValue();
            if (StringUtils.isEmpty(value)) {
                return 0;
            } else {
                return Long.parseLong(value);
            }
        } catch (Exception e) {
            return 0;
        }
    }

    @Override
    public long getParamLongValue(String key, long defaultValue) {
        if (containsParamKey(key)) {
            String value = getParamValue(key);
            if (StringUtils.isEmpty(value)) {
                return defaultValue;
            }
            try {
                return Long.parseLong(value);
            } catch (Exception e) {
                log.debug("cannot conver key[" + key + "]'s value[" + value + "] to long, use default value[" + defaultValue + "]");
                return defaultValue;
            }
        } else {
            log.debug("cannot found key[" + key + "], use default value[" + defaultValue + "]");
            return defaultValue;
        }
    }

    @Override
    public boolean getParamBooleanValue(String key) {
        IParam param = getExtCache(key);
        try {
            if (param == null) {
                return false;
            }
            String value = param.getParamValue();
            if (StringUtils.isEmpty(value)) {
                return false;
            } else {
                return Boolean.parseBoolean(value);
            }
        } catch (Exception e) {
            return false;
        }
    }

    @Override
    public boolean getParamBooleanValue(String key, boolean defaultValue) {
        if (containsParamKey(key)) {
            String value = getParamValue(key);
            if (StringUtils.isEmpty(value)) {
                return defaultValue;
            }
            try {
                return Boolean.parseBoolean(value);
            } catch (Exception e) {
                log.debug("cannot conver key[" + key + "]'s value[" + value + "] to boolean, use default value[" + defaultValue + "]");
                return defaultValue;
            }
        } else {
            log.debug("cannot found key[" + key + "], use default value[" + defaultValue + "]");
            return defaultValue;
        }
    }
}