package cn.ibizlab.core.lite.extensions.model;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import org.springframework.util.ObjectUtils;

import java.util.LinkedHashSet;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class TmpModel {
    @JSONField(ordinal = 3)
    private String id;
    @JSONField(ordinal = 1)
    private String factEntity;
    @JSONField(ordinal = 2)
    private String factEntityName;
    @JSONField(ordinal = 4)
    private LinkedHashSet<String> tables;
    @JSONField(ordinal = 5)
    private LinkedHashSet<ReleationModel> releations = new LinkedHashSet<>();
    @Getter
    @Setter
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class ReleationModel
    {
        @JSONField(ordinal = 1)
        private String entity;
        @JSONField(ordinal = 3)
        private String entityName;
        @JSONField(ordinal = 2)
        private String refEntity;
        @JSONField(ordinal = 4)
        private String refEntityName;
        @JSONField(ordinal = 5)
        private LinkedHashSet<LookupModel> lookups;
    }
    @Getter
    @Setter
    @NoArgsConstructor
    @Accessors(chain = true)
    public static class LookupModel
    {
        @JSONField(ordinal = 1)
        private String field;
        @JSONField(ordinal = 2)
        private String refField;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public DataModel getDataModels()
    {
        DataModel dataModel=new DataModel();
        dataModel.setDataModelName(this.getFactEntity());

        Property property = new Property();
        property.setOwnerDataModel(dataModel);
        property.setPropertyEntity(this.getFactEntity());
        property.setPropertyName(this.getFactEntity());
        property.setSystem("tyyw2plus");
        tables.remove(this.getFactEntity());
        dataModel.getObjectProperties().add(property);
        getPropertyByEntity(dataModel).forEach(item -> dataModel.getObjectProperties().add(item));
        dataModel.setNestedDataModels(getDataModelsByParent(dataModel));


        return dataModel;
    }

    public LinkedHashSet<DataModel> getDataModelsByParent(DataModel parentEntity)
    {
        LinkedHashSet<DataModel> list = new LinkedHashSet<>();
        this.getReleations().forEach(releationModel -> {
            if(releationModel.getRefEntity().equalsIgnoreCase(parentEntity.getDataModelName()))
            {
                DataModel dataModel=new DataModel();
                dataModel.setDataModelName(releationModel.getEntity());
                LinkedHashSet<LayerMapping> layerMappings = new LinkedHashSet<>();
                releationModel.getLookups().forEach(lookupModel -> {
                    LayerMapping layerMapping = new LayerMapping();
                    layerMapping.setSelfPropertyColumn(lookupModel.getField());
                    layerMapping.setParentPropertyColumn(lookupModel.getRefField());
                    layerMappings.add(layerMapping);
                });
                Property property = new Property();
                property.setOwnerDataModel(dataModel);
                property.setPropertyEntity(releationModel.getEntity());
                property.setPropertyName(releationModel.getEntity());
                property.setSystem("tyyw2plus");
                tables.remove(releationModel.getEntity());
                dataModel.getObjectProperties().add(property);

                dataModel.setLayerMappings(layerMappings);
                dataModel.setParentDataModel(parentEntity);
                getPropertyByEntity(dataModel).forEach(item -> dataModel.getObjectProperties().add(item));
                LinkedHashSet<DataModel> nestedDataModels = getDataModelsByParent(dataModel);
                if(!ObjectUtils.isEmpty(nestedDataModels))
                    dataModel.setNestedDataModels(nestedDataModels);

                list.add(dataModel);
            }
        });
        return list;
    }

    public LinkedHashSet<Property> getPropertyByEntity(DataModel dataModel)
    {
        LinkedHashSet<Property> list = new LinkedHashSet<>();
        this.getReleations().forEach(releationModel -> {
            if (releationModel.getEntity().equalsIgnoreCase(dataModel.getFactPorperty().getPropertyEntity())) {

                if(dataModel.getParentDataModel()!=null&&dataModel.getParentDataModel().getDataModelName().equalsIgnoreCase(releationModel.getRefEntity()))
                    return;
                Property property = new Property();
                property.setOwnerDataModel(dataModel);
                property.setPropertyEntity(releationModel.getRefEntity());
                property.setPropertyName(releationModel.getRefEntity());
                property.setSystem("tyyw2plus");
                tables.remove(releationModel.getRefEntity());

                releationModel.getLookups().forEach(lookupModel -> {
                    PropertyMapping propertyMapping = new PropertyMapping();
                    propertyMapping.setSelfPropertyColumn(lookupModel.getRefField());
                    propertyMapping.setSelfProperty(property);
                    propertyMapping.setJoinPropertyColumn(lookupModel.getField());
                    propertyMapping.setJoinPropertyName(releationModel.getEntity());
                    property.getPropertyMappings().add(propertyMapping);
                });

                dataModel.getObjectProperties().add(property);
            }
        });

        return list;
    }
}
