${package}
import com.fastchar.core.FastChar;
import com.fastchar.core.FastEntities;
import com.fastchar.core.FastEntity;
import com.fastchar.database.FastType;
import com.fastchar.database.info.FastColumnInfo;
import com.fastchar.extjs.core.database.FastExtColumnInfo;
import com.fastchar.database.info.FastTableInfo;
import com.fastchar.utils.FastClassUtils;
import com.fastchar.utils.FastEnumUtils;
import com.fastchar.utils.FastStringUtils;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * TargetType枚举类，枚举顺序禁止更改！
 * @author ${author}
 * @date ${datetime}
 */
public enum TargetTypeEnum{
    ${enumValues}
    ;
    public final String text;
    TargetTypeEnum(String text) {
        this.text = text;
    }

    public transient String targetTextColumn;
    public TargetTypeEnum setTargetTextColumn(String columnName) {
        this.targetTextColumn = columnName;
        return this;
    }

    public static Class<? extends FastEntity<?>> getTargetClass(int targetType) {
        try {
            if(targetType<0){
                return null;
            }
            TargetTypeEnum targetTypeEnum = FastEnumUtils.formatToEnum(TargetTypeEnum.class, targetType);
            if (targetTypeEnum != null) {
                List<FastEntities.EntityInfo> entityInfos = FastChar.getEntities().getEntityInfos();
                for (FastEntities.EntityInfo entityInfo : entityInfos) {
                    if (entityInfo.getTargetClass().getSimpleName().equals(targetTypeEnum.name())) {
                        return entityInfo.getTargetClass();
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static FastEntity<?> getTargetEntity(int targetType,int targetId) {
        try {
            Class<? extends FastEntity<?>> targetClass = getTargetClass(targetType);
            if (targetClass != null) {
                return targetClass.newInstance().selectById(targetId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static FastEntity<?> getTargetDetails(int targetType,int targetId) {
        try {
            Class<? extends FastEntity<?>> targetClass = getTargetClass(targetType);
            if (targetClass != null) {
                List<Method> getDetails = FastClassUtils.getMethod(targetClass, "getDetails");
                if (getDetails.size() > 0) {
                    return (FastEntity<?>) getDetails.get(0).invoke(targetClass.newInstance(), targetId);
                }
                return getTargetEntity(targetType, targetId);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

     public static List<String> getTargetLeftJoinSql(List<String> linkColumns, TargetTypeEnum... targetTypeEnums) {
        List<String> sqlList = new ArrayList<>();
        try {
            if (targetTypeEnums.length == 0) {
                targetTypeEnums = TargetTypeEnum.values();
            }
            for (TargetTypeEnum targetTypeEnum : targetTypeEnums) {
                Class<? extends FastEntity<?>> targetClass = getTargetClass(targetTypeEnum.ordinal());
                if (targetClass != null) {
                    FastEntity<?> entity = targetClass.newInstance();
                    List<FastColumnInfo<?>> primaries = entity.getPrimaries();
                    if (primaries.isEmpty()) {
                        continue;
                    }
                    String alias = "tgt" + targetTypeEnum.ordinal();
                    String sqlStr = " left join " + entity.getTableName() + " as " + alias +
                            "  on " + alias + "." + primaries.get(0).getName()
                            + " = t.targetId and t.targetType = " + targetTypeEnum.ordinal();

                    linkColumns.addAll(entity.toSelectColumns(alias));
                    sqlList.add(sqlStr);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return sqlList;
    }

    public static void putTargetEntity(FastEntity<?> currEntity, TargetTypeEnum... targetTypeEnums) {
        if (targetTypeEnums.length == 0) {
            targetTypeEnums = TargetTypeEnum.values();
        }
        for (TargetTypeEnum targetTypeEnum : targetTypeEnums) {
            Class<? extends FastEntity<?>> targetClass = getTargetClass(targetTypeEnum.ordinal());
            if (targetClass != null) {
                String alias = "tgt" + targetTypeEnum.ordinal();
                currEntity.put("target", currEntity.toEntity(alias, targetClass));
            }
        }
    }


    public static void getTargetLeftJoinUnionAllSql(List<String> targetSql, TargetTypeEnum... targetTypeEnums) {
        try {
            if (targetTypeEnums.length == 0) {
                targetTypeEnums = TargetTypeEnum.values();
            }
            for (TargetTypeEnum targetTypeEnum : targetTypeEnums) {
                Class<? extends FastEntity<?>> targetClass = getTargetClass(targetTypeEnum.ordinal());
                if (targetClass != null) {
                    FastEntity<?> entity = targetClass.newInstance();
                    String targetIdColumnName = entity.getPrimaries().get(0).getName();
                    if (FastStringUtils.isEmpty(targetTypeEnum.targetTextColumn)) {
                        targetTypeEnum.targetTextColumn = guessTableTextColumn(entity.getTable(), targetIdColumnName);
                    }
                    targetSql.add("select " + targetTypeEnum.ordinal() + "," + targetIdColumnName + ","
                            + targetTypeEnum.targetTextColumn + " from " + entity.getTableName());
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private static String guessTableTextColumn(FastTableInfo<?> tableInfo,String defaultTextColumn) {
        if (tableInfo == null) {
            return defaultTextColumn;
        }
        String[] guessKeys = new String[]{"name", "title", "info", "content", "info", "details", "code"};

        for (String guessKey : guessKeys) {
            for (FastColumnInfo<?> column : tableInfo.getColumns()) {
                FastExtColumnInfo columnInfo = (FastExtColumnInfo) column;
                if (columnInfo.isLayer()) {
                    continue;
                }
                if (columnInfo.isLink()) {
                    continue;
                }

                if (FastType.isByteArrayType(column.getType())) {
                    continue;
                }

                if (FastType.isBigStringType(column.getType())) {
                    continue;
                }
                if (FastType.isStringType(column.getType())) {
                    if (column.getName().toLowerCase().contains(guessKey)) {
                        return column.getName();
                    }
                }
            }
        }
        for (FastColumnInfo<?> column : tableInfo.getColumns()) {
            FastExtColumnInfo columnInfo = (FastExtColumnInfo) column;
            if (columnInfo.isLayer()) {
                continue;
            }
            if (columnInfo.isLink()) {
                continue;
            }

            if (FastType.isStringType(column.getType())) {
                return column.getName();
            }
        }
        return defaultTextColumn;
    }

}