package cn.stylefeng.team.project.modular.filing.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.RandomUtil;
import cn.hutool.extra.spring.SpringUtil;
import cn.stylefeng.roses.kernel.rule.enums.YesOrNotEnum;
import cn.stylefeng.team.meta.api.MetaFieldServiceApi;
import cn.stylefeng.team.meta.api.entity.MetaDefinition;
import cn.stylefeng.team.meta.api.entity.MetaField;
import cn.stylefeng.team.meta.api.entity.MetaModel;
import cn.stylefeng.team.meta.api.enums.MetaFieldTypeEnum;
import cn.stylefeng.team.meta.api.enums.MetaModelTypeEnum;
import cn.stylefeng.team.project.api.SystemCodeApi;
import cn.stylefeng.team.project.api.entity.Business;
import cn.stylefeng.team.project.api.enums.SystemCodeTypeEnum;
import cn.stylefeng.team.project.api.pojo.SystemCodeInfo;
import cn.stylefeng.team.project.modular.filing.constants.BevProdConstants;
import cn.stylefeng.team.project.modular.filing.pojo.aidesign.aiparse.business.ParseField;
import cn.stylefeng.team.project.modular.filing.pojo.aidesign.aiparse.business.ParseModel;
import cn.stylefeng.team.project.modular.filing.pojo.aidesign.aiparse.dto.ParseModelPackageDTO;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import static cn.hutool.core.util.RandomUtil.BASE_CHAR;

public class AiBusinessModelFactory {

    public static ParseModelPackageDTO createParseModelPackage(Business business, List<ParseModel> parseModelList) {

        List<MetaModel> metaModelList = new ArrayList<>();
        List<MetaDefinition> metaDefinitionList = new ArrayList<>();
        List<MetaField> totalMetaFieldList = new ArrayList<>();

        SystemCodeApi systemCodeApi = SpringUtil.getBean(SystemCodeApi.class);
        SystemCodeInfo baseSystemCode = systemCodeApi.createNewSystemCode(SystemCodeTypeEnum.MODEL);

        int modelSort = 10;
        for (int i = 0; i < parseModelList.size(); i++) {

            ParseModel parseModel = parseModelList.get(i);

            MetaModel metaModel = new MetaModel();
            BeanUtil.copyProperties(parseModel, metaModel, CopyOptions.create().ignoreError());

            metaModel.setMetaModelCode(BevProdConstants.MODEL_TABLE_PREFIX + metaModel.getMetaModelCode() + "_" + RandomUtil.randomString(BASE_CHAR, 8));
            metaModel.setMetaModelId(IdWorker.getId());
            metaModel.setBusinessCategoryId(business.getBusinessCategoryId());
            metaModel.setBusinessId(business.getBusinessId());

            SystemCodeInfo newCode = systemCodeApi.addNumber(SystemCodeTypeEnum.MODEL, baseSystemCode.getSystemCode(), i);
            metaModel.setSystemCode(newCode.getSystemCode());
            metaModel.setSystemCodeShow(newCode.getSystemCodeShow());

            metaModel.setCurrentVersion("1.0");

            metaModel.setMetaModelType(MetaModelTypeEnum.NEW_MODEL.getCode());
            metaModel.setMainFlag(YesOrNotEnum.N.getCode());
            metaModel.setSubTableFieldCode(BevProdConstants.LINK_MAIN_ID_FIELD_NAME);
            metaModel.setFldSort(new BigDecimal(modelSort));

            metaModelList.add(metaModel);

            modelSort = modelSort + 10;

            MetaDefinition metaDefinition = new MetaDefinition();
            metaDefinition.setMetaDefinitionId(IdWorker.getId());
            metaDefinition.setBusinessCategoryId(business.getBusinessCategoryId());
            metaDefinition.setBusinessId(business.getBusinessId());
            metaDefinition.setMetaModelId(metaModel.getMetaModelId());
            metaDefinition.setFldVersion("1.0");
            metaModel.setCurrentDefinitionId(metaDefinition.getMetaDefinitionId());

            metaDefinitionList.add(metaDefinition);

            List<ParseField> fieldList = parseModel.getFieldList();
            List<MetaField> thisModelMetaFieldList = new ArrayList<>();
            if (ObjectUtil.isNotEmpty(fieldList)) {
                int fieldSort = 10;
                for (ParseField parseField : fieldList) {
                    MetaField metaField = new MetaField();
                    BeanUtil.copyProperties(parseField, metaField, CopyOptions.create().ignoreError());

                    metaField.setFieldId(IdWorker.getId());
                    metaField.setBusinessCategoryId(business.getBusinessCategoryId());
                    metaField.setBusinessId(business.getBusinessId());
                    metaField.setMetaModelId(metaModel.getMetaModelId());
                    metaField.setMetaDefinitionId(metaDefinition.getMetaDefinitionId());
                    metaField.setRealFlag(YesOrNotEnum.Y.getCode());
                    metaField.setFldSort(new BigDecimal(fieldSort));
                    if (YesOrNotEnum.Y.getCode().equals(metaField.getKeyFlag())) {
                        metaField.setNotEmptyFlag(YesOrNotEnum.Y.getCode());
                    } else {
                        metaField.setNotEmptyFlag(YesOrNotEnum.N.getCode());
                    }

                    thisModelMetaFieldList.add(metaField);

                    fieldSort = fieldSort + 10;

                    if (fieldSort == 20) {
                        thisModelMetaFieldList.add(createLinkMainTableIdField(business, metaDefinition));
                        fieldSort = fieldSort + 10;
                    }

                }

                thisModelMetaFieldList.add(createTimeField(business, metaDefinition));
                thisModelMetaFieldList.add(createUserField(business, metaDefinition));
                thisModelMetaFieldList.add(updateTimeField(business, metaDefinition));
                thisModelMetaFieldList.add(updateUserField(business, metaDefinition));

                metaModel.setMetaFieldList(thisModelMetaFieldList);

                totalMetaFieldList.addAll(thisModelMetaFieldList);
            }
        }

        SystemCodeInfo prodMainSystemCode = systemCodeApi.addNumber(SystemCodeTypeEnum.MODEL, baseSystemCode.getSystemCode(), parseModelList.size());
        MetaModel prodMainLinkModel = createProdMainLinkModel(business, prodMainSystemCode);

        metaModelList.add(prodMainLinkModel);

        ParseModelPackageDTO parseModelPackageDTO = new ParseModelPackageDTO();
        parseModelPackageDTO.setMetaModelList(metaModelList);
        parseModelPackageDTO.setMetaDefinitionList(metaDefinitionList);
        parseModelPackageDTO.setMetaFieldList(totalMetaFieldList);
        return parseModelPackageDTO;
    }

    private static MetaField createTimeField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = createCommonField(business, metaDefinition);
        metaField.setFieldType(MetaFieldTypeEnum.DATE_TIME.getCode());
        metaField.setFieldCode("create_time");
        metaField.setDescription("创建时间");
        metaField.setFldSort(new BigDecimal(1000));
        return metaField;
    }

    private static MetaField updateTimeField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = createCommonField(business, metaDefinition);
        metaField.setFieldType(MetaFieldTypeEnum.DATE_TIME.getCode());
        metaField.setFieldCode("update_time");
        metaField.setDescription("更新时间");
        metaField.setFldSort(new BigDecimal(1030));
        return metaField;
    }

    private static MetaField createUserField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = createCommonField(business, metaDefinition);
        metaField.setFieldType(MetaFieldTypeEnum.BIGINT.getCode());
        metaField.setFieldCode("create_user");
        metaField.setDescription("创建人");
        metaField.setFldSort(new BigDecimal(1010));
        return metaField;
    }

    private static MetaField updateUserField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = createCommonField(business, metaDefinition);
        metaField.setFieldType(MetaFieldTypeEnum.BIGINT.getCode());
        metaField.setFieldCode("update_user");
        metaField.setDescription("更新人");
        metaField.setFldSort(new BigDecimal(1040));
        return metaField;
    }

    private static MetaField createLinkMainTableIdField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = createCommonField(business, metaDefinition);
        metaField.setFieldType(MetaFieldTypeEnum.BIGINT.getCode());
        metaField.setFieldCode(BevProdConstants.LINK_MAIN_ID_FIELD_NAME);
        metaField.setDescription("关联主填报表的id");
        metaField.setFldSort(new BigDecimal(20));
        return metaField;
    }

    private static MetaField createCommonField(Business business, MetaDefinition metaDefinition) {
        MetaField metaField = new MetaField();
        metaField.setFieldId(IdWorker.getId());
        metaField.setBusinessCategoryId(business.getBusinessCategoryId());
        metaField.setBusinessId(business.getBusinessId());
        metaField.setMetaModelId(metaDefinition.getMetaModelId());
        metaField.setMetaDefinitionId(metaDefinition.getMetaDefinitionId());
        metaField.setFieldLength(0);
        metaField.setDecimalLength(0);
        metaField.setNotEmptyFlag(YesOrNotEnum.N.getCode());
        metaField.setKeyFlag(YesOrNotEnum.N.getCode());
        metaField.setRealFlag(YesOrNotEnum.Y.getCode());
        return metaField;
    }

    private static MetaModel createProdMainLinkModel(Business business, SystemCodeInfo systemCodeInfo) {
        MetaModel metaModel = new MetaModel();
        metaModel.setMetaModelId(IdWorker.getId());
        metaModel.setBusinessCategoryId(business.getBusinessCategoryId());
        metaModel.setBusinessId(business.getBusinessId());
        metaModel.setMetaModelName(BevProdConstants.BEV_PROD_MAIN_TABLE_NAME);
        metaModel.setMetaModelCode(BevProdConstants.BEV_PROD_MAIN_TABLE);
        metaModel.setSystemCode(systemCodeInfo.getSystemCode());
        metaModel.setSystemCodeShow(systemCodeInfo.getSystemCodeShow());
        metaModel.setCurrentVersion("1.0");
        metaModel.setMetaModelType(MetaModelTypeEnum.OUT_MODEL.getCode());
        metaModel.setLinkModelId(BevProdConstants.BEV_PROD_MAIN_TABLE_MODEL_ID);
        metaModel.setMainFlag(YesOrNotEnum.Y.getCode());
        metaModel.setFldSort(new BigDecimal(1));

        MetaFieldServiceApi metaFieldServiceApi = SpringUtil.getBean(MetaFieldServiceApi.class);
        List<MetaField> mainModelFieldList = metaFieldServiceApi.getFieldListByModelId(YesOrNotEnum.Y.getCode(), metaModel.getLinkModelId());
        metaModel.setMetaFieldList(mainModelFieldList);

        return metaModel;
    }

}
