package com.jwipc.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.metadata.GlobalConfiguration;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.metadata.property.ExcelContentProperty;

import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;

/**
 * <p> </p>
 *
 * @author ZhangJie
 * @version 1.0
 * @since JDK 1.8
 */
public class ExcelDictConverter implements Converter<String> {

    @Override
    public Class<String> supportJavaTypeKey() {
        return String.class;
    }

    private final Map<String, Map<String, String>> cache = new HashMap<>();
    private final Function<String, Map<String, String>> dictFunction;

    public ExcelDictConverter(Function<String, Map<String, String>> dictFunction) {
        this.dictFunction = dictFunction;
    }

    @Override
    public WriteCellData<String> convertToExcelData(String value, ExcelContentProperty contentProperty,
                                                    GlobalConfiguration globalConfiguration) throws Exception
    {
        if (contentProperty == null || contentProperty.getField() == null) {
            return new WriteCellData(value);
        }
        if (StrUtil.isEmpty(value)) {
            return new WriteCellData(value);
        }
        ExcelDict dict = contentProperty.getField().getAnnotation(ExcelDict.class);
        if (Objects.nonNull(dict)) {
            final String code = dict.value();
            final Map<String, String> stringStringMap = cache.get(code);
            if (CollUtil.isEmpty(stringStringMap)) {
                Map<String, String> a = this.dictFunction.apply(code);
                if (CollUtil.isEmpty(a)) {
                    return new WriteCellData(value);
                }
                cache.put(code, a);
                final String stringValue = a.get(value);
                if (StrUtil.isEmpty(stringValue)) {
                    return new WriteCellData(value);
                }
                return new WriteCellData(stringValue);
            } else {
                final String stringValue = stringStringMap.get(value);
                if (StrUtil.isEmpty(stringValue)) {
                    return new WriteCellData(value);
                }
                return new WriteCellData(stringValue);
            }
        }
        return new WriteCellData(value);
    }
}
