import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.MapUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;

import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;


@Slf4j
public class I18nKeyReplaceServiceImpl implements I18nKeyReplaceService {

    @Value("${cms.i18n.switch:true}")
    private Boolean configSwitch;

    @Value("${cms.i18n.debugLog.switch:true}")
    private boolean enableLog;

    private final String LANGUAGE_TAG = "__LANG__";

    /**
     * @param data          业务数据json
     * @param language      语言
     * @param removeI18nKey 是否删除国际化多语言字段
     * @return 结果
     */
    @Override
    public String handleI18n(String data, String language, boolean removeI18nKey) {
        if (configSwitch == null || !configSwitch) {
            return data;
        }

        if (StringUtils.isBlank(data) || StringUtils.isBlank(language)) {
            return data;
        }

        if (enableLog && log.isDebugEnabled()) {
            log.debug("handleI18n request, language={} removeI18nKey={} data={}", language, removeI18nKey, data);
        }

        Object newData = null;
        if (this.isArray(data)) {
            List<Object> list = JsonUtils.jsonToList(data);
            listAndMap(list, language, removeI18nKey);
            newData = list;
        } else {
            Map<String, Object> dataMap = JsonUtils.jsonToMap(data);
            handleI18n(dataMap, language, removeI18nKey);
            newData = dataMap;
        }

        String result = JsonUtils.objectToJson(newData);

        if (enableLog && log.isDebugEnabled()) {
            log.debug("handleI18n response, result={}", result);
        }
        return result;
    }

    /**
     * @param keyMap        业务数据json
     * @param language      语言
     * @param removeI18nKey 是否删除国际化多语言字段
     * @return 结果
     */
    @Override
    public Map<String, Object> handleI18n(Map<String, Object> keyMap, String language, boolean removeI18nKey) {
        if (MapUtils.isEmpty(keyMap)) {
            return keyMap;
        }

        if (enableLog && log.isDebugEnabled()) {
            log.debug("handleI18n request map, language={} removeI18nKey={} keyMap={}", language, removeI18nKey, JsonUtils.objectToJson(keyMap));
        }

        Set<String> keysRemoved = new HashSet<>(0);//需要删除的key
        Set<String> keys = new HashSet<>(keyMap.keySet());
        for (String key : keys) {
            Object value = keyMap.get(key);
            //1.处理KEY
            if (key.contains(LANGUAGE_TAG)) {
                String languageSuffix = this.addLanguageTag(language);
                if (key.endsWith(languageSuffix)) {
                    String originalKey = removeLanguageSuffixIfExist(key, languageSuffix);
                    keyMap.put(originalKey, value);
                }

                //移除多语言字段
                if (removeI18nKey) {
                    keysRemoved.add(key);
                }
                continue;
            }

            //2.处理Value,继续多语言字段值替换
            if (value instanceof Map) {
                handleI18n((Map) value, language, removeI18nKey);
            } else if (value instanceof List) {
                listAndMap((List) value, language, removeI18nKey);
            } else if (value instanceof String) {
                if (this.isArray((String) value)) {
                    List<Object> list = JsonUtils.jsonToList((String) value);
                    listAndMap(list, language, removeI18nKey);
                    keyMap.put(key, JsonUtils.objectToJson(list));
                }
            }
        }
        //删除key
        if (!keysRemoved.isEmpty()) {
            removeAllI18nKey(keyMap, keysRemoved);
        }

        if (enableLog && log.isDebugEnabled()) {
            log.debug("handleI18n response map, result={}", JsonUtils.objectToJson(keyMap));
        }
        return keyMap;
    }

    private boolean isArray(String jsonStr) {
        return StringUtils.isNotBlank(jsonStr) && jsonStr.startsWith("[");
    }

    /**
     * list 集合处理
     *
     * @param list
     * @param language
     * @param removeI18nKey
     */
    private void listAndMap(List list, String language, boolean removeI18nKey) {
        if (list.size() > 0 && list.get(0) instanceof Map) {
            for (Object o : list) {
                handleI18n((Map) o, language, removeI18nKey);
            }
        }
    }

    /**
     * @param language
     * @return
     */
    private String buildLanguageSuffix(String language) {
        return LANGUAGE_TAG + language;
    }

    /**
     * @param key
     * @param languageSuffix
     * @return
     */
    private String removeLanguageSuffixIfExist(String key, String languageSuffix) {
        return key.substring(0, key.lastIndexOf(languageSuffix));
    }

    /**
     * @param key
     * @return
     */
    private String addLanguageTag(String key) {
        return LANGUAGE_TAG + key;
    }


    private void removeAllI18nKey(Map<String, Object> pageKeyMap, Set<String> removeKey) {
        pageKeyMap.keySet().removeAll(removeKey);
    }

    public void setConfigSwitch(Boolean configSwitch) {
        this.configSwitch = configSwitch;
    }
}