package org.springblade.datasource.transform;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.google.common.base.Enums;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springblade.core.tool.exception.ServiceException;
import org.springblade.datasource.enums.DsTypeEnum;
import org.springblade.datasource.transform.general.GeneralEnum;
import org.springblade.datasource.transform.general.GeneralModel;
import org.springblade.datasource.transform.seatunnel.SeatunnelColumnType;
import org.springblade.etl.entity.SqlColumn;
import org.springblade.etl.entity.bi.ReportDatasource;
import org.springframework.stereotype.Component;

import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author 喜欢番茄火锅
 * @date 2023/8/21 10:57
 */
@Slf4j
@Component
public class TransformContext {

    private final Map<DsTypeEnum, ITransform> transformMap = new ConcurrentHashMap<>();

    public TransformContext(List<ITransform> transforms) {
        log.info(":::::::[开始]注入转换-建表插件:::::::");
        transforms.forEach(item -> {
            log.info("=====>>注入转换插件:{}", item.dsType().name());
            transformMap.put(item.dsType(), item);
        });
        log.info(":::::::[结束]注入转换-建表插件:::::::");
    }

    public static void main(String[] args) {
        String str = "用户'1'表01";
        String replace = str.replace("'", "`");
        System.out.println(replace);
    }

    public SeatunnelColumnType transformToSeatunnelType(DsTypeEnum dsType, String columnType) {
        if (StrUtil.isBlank(columnType)) {
            throw new ServiceException("字段类型不可为空!");
        }
        if (dsType == null) {
            throw new ServiceException("数据源类型不可为空!");
        }
        ITransform transform = getTransform(dsType);
        return transform.transformToSeatunnelType(columnType);
    }

    private ITransform getTransform(DsTypeEnum dsType) {
        ITransform transform = transformMap.get(dsType);
        if (transform == null) {
            throw new ServiceException("翻译组件暂不支持该数据源类型!" + dsType);
        }
        return transform;
    }

    public List<ColumnInfo> transformColumns(ReportDatasource targetDatasource, List<GeneralModel> model, List<SqlColumn> info) {
        ITransform transform = getTransform(targetDatasource.getDsTypeSyl());
        return transform.transformColumns(model, info);
    }

    public List<ColumnInfo> transformColumns(Integer sourceDsType, List<GeneralModel> model, List<SqlColumn> info) {
        ITransform transform = getTransform(DsTypeEnum.resolve(sourceDsType));
        return transform.transformColumns(model, info);
    }

    @SneakyThrows
    public List<ColumnInfo> getSourceColumn(String tableViewName, ReportDatasource datasource) {
        ITransform transform = getTransform(DsTypeEnum.resolve(datasource.getDsType()));
        return transform.getSourceColumn(tableViewName, datasource);
    }


    public void transformAndCreatTable(ReportDatasource sourceDatasource, ReportDatasource targetDatasource, List<GeneralModel> model, String sourceTableName, String creatTableName, String tableComment, boolean deleteSourceTable) {
        ITransform transform = getTransform(sourceDatasource.getDsTypeSyl());
        ITransform creat = getTransform(targetDatasource.getDsTypeSyl());

        model.stream().forEach(v -> {
            if (!v.getSourceColumn() && !Enums.getIfPresent(GeneralEnum.class, v.getType().toUpperCase(Locale.ROOT)).isPresent()) {
                log.error("转换模型字段类型错误!,GeneralModel:{}", JSONUtil.toJsonStr(v));
                throw new ServiceException("错误得转换模型字段类型:" + v.getType() + "!");
            }
        });
        TableInfo tableInfo = transform.parseTableInfo(sourceDatasource, model, sourceTableName, tableComment);
        if (tableInfo == null) {
            log.error("转换模型TableInfo不能为空!,tableInfo:{}", JSONUtil.toJsonStr(tableInfo));
            throw new ServiceException("转换模型TableInfo不能为空!");
        }
        if (CollectionUtil.isEmpty(tableInfo.getColumnInfo())) {
            log.error("转换模型字段列表不能为空!,tableInfo:{}", JSONUtil.toJsonStr(tableInfo));
            throw new ServiceException("转换模型字段列表不能为空!");
        }
        if (tableInfo.getColumnInfo().stream().anyMatch(v -> StringUtils.isEmpty(v.getColumnName()))) {
            log.error("转换模型字段名称不能为空!,tableInfo:{}", JSONUtil.toJsonStr(tableInfo));
            throw new ServiceException("转换模型字段名称不能为空!");
        }


        tableInfo.setTableName(creatTableName);
        tableInfo.setTableComment(Optional.ofNullable(tableInfo.getTableComment()).orElse("").replace("'", "`"));
        tableInfo.getColumnInfo().stream().forEach(v -> v.setColumnComments(Optional.ofNullable(v.getColumnComments()).orElse("").replace("'", "`")));
        log.info("自动建表参数,tableInfo={},targetDatasource={},deleteSourceTable,{}", tableInfo, targetDatasource, deleteSourceTable);
        creat.creatTable(tableInfo, targetDatasource, deleteSourceTable);
    }
}
