package cn.stylefeng.team.meta.modular.factory;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.team.meta.api.entity.MetaField;
import cn.stylefeng.team.meta.api.pojo.db.DatabaseFieldDTO;
import cn.stylefeng.team.meta.api.pojo.db.DatabaseTableDTO;
import cn.stylefeng.team.meta.sdk.util.TableSchemaCreateUtil;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Slf4j
public class CalcFieldSortFactory {

    public static String compareAndCalcFieldOrder(List<MetaField> metaFieldList, DatabaseTableDTO dbTableFieldList) {


        Map<String, String> needSortFieldAfterList = new HashMap<>();

        Map<String, MetaField> needSortFieldDetailList = new HashMap<>();

        List<DatabaseFieldDTO> dbFieldList = dbTableFieldList.getGenDatabaseFieldDtoList();

        for (int i = 0; i < metaFieldList.size(); i++) {

            if (i >= dbFieldList.size()) {
                break;
            }

            MetaField metaField = metaFieldList.get(i);
            DatabaseFieldDTO databaseField = dbFieldList.get(i);

            if (!StrUtil.equals(metaField.getFieldCode(), databaseField.getFieldCode())) {

                if (getExistedFlag(databaseField.getFieldCode(), dbFieldList)) {

                    int thisFieldBeforeIndex = i - 1;
                    if (thisFieldBeforeIndex < 0) {
                        continue;
                    }

                    String beforeFieldCode = metaFieldList.get(thisFieldBeforeIndex).getFieldCode();
                    needSortFieldAfterList.put(databaseField.getFieldCode(), beforeFieldCode);
                    needSortFieldDetailList.put(databaseField.getFieldCode(), metaField);
                }
            }
        }

        String alterSql = createAlterSql(dbTableFieldList.getTableName(), needSortFieldAfterList, needSortFieldDetailList);
        log.info("生成的alter语句为：{}", alterSql);
        return alterSql;
    }

    public static boolean getExistedFlag(String fieldCode, List<DatabaseFieldDTO> dbFieldList) {
        for (DatabaseFieldDTO databaseFieldDTO : dbFieldList) {
            if (StrUtil.equals(fieldCode, databaseFieldDTO.getFieldCode())) {
                return true;
            }
        }
        return false;
    }

    public static String createAlterSql(String tableName, Map<String, String> needSortFieldAfterList, Map<String, MetaField> needSortFieldDetailList) {

        if (ObjectUtil.isAllEmpty(needSortFieldAfterList, needSortFieldDetailList)) {
            return null;
        }

        StringBuilder alterSql = new StringBuilder();

        alterSql.append("alter table `").append(tableName).append("` \n");

        if (ObjectUtil.isNotEmpty(needSortFieldAfterList)) {

            for (Map.Entry<String, String> entry : needSortFieldAfterList.entrySet()) {

                String fieldCode = entry.getKey();
                String afterFieldCode = entry.getValue();
                MetaField metaFieldDetail = needSortFieldDetailList.get(fieldCode);

                alterSql.append("modify column ").append(TableSchemaCreateUtil.fieldTypeMetaCreate(metaFieldDetail)).append(" after `").append(afterFieldCode).append("`,\n");
            }
        }

        return StrUtil.removeSuffix(alterSql.toString(), ",\n") + ";";
    }

}
