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

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import cn.stylefeng.team.meta.api.entity.MetaField;
import cn.stylefeng.team.meta.api.pojo.MetaModelCreatSqlDTO;
import cn.stylefeng.team.meta.modular.pojo.GenerationFieldSql;
import cn.stylefeng.team.meta.modular.pojo.GenerationSql;
import cn.stylefeng.team.meta.sdk.parser.MetaFieldTypeToJavaType;
import cn.stylefeng.team.meta.sdk.parser.MysqlTypeToMetaFieldType;
import cn.stylefeng.team.meta.sdk.parser.OracleTypeToMetaFieldType;
import cn.stylefeng.team.meta.sdk.parser.PgSqlTypeToMetaFieldType;

import java.util.ArrayList;
import java.util.List;

public class CreateTableMetaFactory {

    public static GenerationSql generationSql(MetaModelCreatSqlDTO metaModelCreatSqlDTO) {

        GenerationSql generationSql = new GenerationSql();
        BeanUtil.copyProperties(metaModelCreatSqlDTO, generationSql, CopyOptions.create().ignoreError());

        List<MetaField> metaFieldCreatSqlList = metaModelCreatSqlDTO.getMetaFieldList();
        if (ObjectUtil.isEmpty(metaFieldCreatSqlList)) {
            return generationSql;
        }

        List<GenerationFieldSql> generationFieldList = createGenerationSqlField(metaFieldCreatSqlList);
        generationSql.setGenerationFieldList(generationFieldList);

        for (GenerationFieldSql generationField : generationFieldList) {

            if (YesOrNotEnum.Y.getCode().equalsIgnoreCase(generationField.getKeyFlag())) {
                generationSql.setPrimaryKeyField(generationField.getFieldCode());
            }
        }

        return generationSql;
    }

    public static List<GenerationFieldSql> createGenerationSqlField(List<MetaField> metaFieldList) {

        List<GenerationFieldSql> generationFieldList = new ArrayList<>();
        for (MetaField metaField : metaFieldList) {

            GenerationFieldSql generationField = new GenerationFieldSql();
            BeanUtil.copyProperties(metaField, generationField, CopyOptions.create().ignoreError());

            String fieldCode = metaField.getFieldCode();
            if (StrUtil.isBlank(fieldCode)) {
                continue;
            }

            CreateTableMetaFactory.getMysqlConfig(generationField, metaField);

            CreateTableMetaFactory.getOracleConfig(generationField, metaField);

            CreateTableMetaFactory.getPgsqlConfig(generationField, metaField);

            generationFieldList.add(generationField);
        }

        return generationFieldList;
    }

    private static void getMysqlConfig(GenerationFieldSql generationField, MetaField metaField) {

        generationField.setMysqlType(MysqlTypeToMetaFieldType.getSqlType(metaField.getFieldType()));

        generationField.setMysqlLength(MysqlTypeToMetaFieldType.getLengthResult(metaField.getFieldType(), metaField.getFieldLength(),
                metaField.getDecimalLength()));

        generationField.setMysqlNull(YesOrNotEnum.Y.getKey().equals(metaField.getNotEmptyFlag()) ? " NOT NULL " : " NULL DEFAULT NULL");

        if ("String".equals(MetaFieldTypeToJavaType.getJavaType(metaField.getFieldType()))) {
            generationField.setMysqlCharacterSet("CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ");
        }

        generationField.setDefaultValue(
                ObjectUtil.isEmpty(metaField.getDefaultValue()) ? "" : "DEFAULT '" + metaField.getDefaultValue() + "'");
    }

    private static void getOracleConfig(GenerationFieldSql generationField, MetaField metaField) {

        generationField.setOracleType(OracleTypeToMetaFieldType.getSqlType(metaField.getFieldType()));

        generationField.setOracleLength(OracleTypeToMetaFieldType.getLengthResult(metaField.getFieldType(), metaField.getFieldLength(),
                metaField.getDecimalLength()));

        generationField.setOtherNull(YesOrNotEnum.Y.getKey().equals(metaField.getNotEmptyFlag()) ? " NOT NULL " : "");
    }

    private static void getPgsqlConfig(GenerationFieldSql generationField, MetaField metaField) {

        generationField.setPgsqlType(PgSqlTypeToMetaFieldType.getSqlType(metaField.getFieldType()));

        generationField.setPgsqlLength(PgSqlTypeToMetaFieldType.getLengthResult(metaField.getFieldType(), metaField.getFieldLength(),
                metaField.getDecimalLength()));

        if ("varchar".equals(PgSqlTypeToMetaFieldType.getSqlType(metaField.getFieldType())) || "text".equals(
                PgSqlTypeToMetaFieldType.getSqlType(metaField.getFieldType()))) {
            generationField.setPgsqlCharacterSet("COLLATE \"pg_catalog\".\"default\"");
        }

    }

    public static GenerationFieldSql commonGetMysqlConfig(Integer fieldType,
                                                          Integer fieldLength,
                                                          Integer decimalLength,
                                                          String notEmptyFlag,
                                                          String defaultValue) {

        GenerationFieldSql generationFieldSql = new GenerationFieldSql();

        generationFieldSql.setMysqlType(MysqlTypeToMetaFieldType.getSqlType(fieldType));

        generationFieldSql.setMysqlLength(MysqlTypeToMetaFieldType.getLengthResult(fieldType, fieldLength,
                decimalLength));

        generationFieldSql.setMysqlNull(YesOrNotEnum.Y.getKey().equals(notEmptyFlag) ? " NOT NULL " : " NULL DEFAULT NULL");

        if ("String".equals(MetaFieldTypeToJavaType.getJavaType(fieldType))) {
            generationFieldSql.setMysqlCharacterSet("CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ");
        }

        generationFieldSql.setDefaultValue(
                ObjectUtil.isEmpty(defaultValue) ? "" : "DEFAULT '" + defaultValue + "'");

        return generationFieldSql;
    }

}
