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

import cn.ibizlab.core.lite.extensions.domain.EntityModel;
import cn.ibizlab.core.lite.extensions.domain.ModelObj;
import cn.ibizlab.core.lite.extensions.util.LiteStorage;
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.StringUtils;

import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class Property {



    @JsonIgnore
    @JSONField(serialize = false)
    private DataModel ownerDataModel;

    @JsonIgnore
    @JSONField(serialize = false)
    public DataModel getRootDataModel()
    {
        return this.getOwnerDataModel().getRootDataModel();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Property getRootFactPorperty()
    {
        return this.getOwnerDataModel().getRootFactPorperty();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Property getFactPorperty()
    {
        return this.getOwnerDataModel().getFactPorperty();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public int getLayerNo()
    {
        return this.getOwnerDataModel().getLayerNo();
    }

    @JSONField(ordinal = 1)
    private String propertyName;

    @JSONField(ordinal = 2)
    private String system;

    @JSONField(ordinal = 3)
    private String propertyEntity;

    @JSONField(ordinal = 4)
    private LinkedHashSet<PropertyMapping> propertyMappings = new LinkedHashSet<>();
    public void setPropertyMappings(LinkedHashSet<PropertyMapping> propertyMappings)
    {
        if(propertyMappings!=null)
        {
            propertyMappings.forEach(propertyMapping -> propertyMapping.setSelfProperty(this));
            this.propertyMappings=propertyMappings;
        }
    }


    @Override
    public String toString() {
        return "Property{" +
                "propertyName='" + getPropertyName() + '\'' +
                ", system='" + getSystem() + '\'' +
                ", propertyEntity='" + getPropertyEntity() + '\'' +
                ", propertyMappings=" + getPropertyMappings() +
                "}\r\n";
    }


    @JsonIgnore
    @JSONField(serialize = false)
    private EntityModel entityModel;

    @JsonIgnore
    @JSONField(serialize = false)
    public synchronized EntityModel getEntityModel()
    {
        if(entityModel==null)
            entityModel= LiteStorage.getLiteModelService().getProxyEntityModel(this.getSystem(),this.getPropertyEntity());
        return entityModel;
    }


    public String lookup(List<ModelObj> modelObjList)
    {
        String sql="";
        Set<String> conds= new LinkedHashSet<>();
        if(propertyMappings.size()>0)
        {
            for(PropertyMapping mapping:propertyMappings){
                if (!StringUtils.isEmpty(sql))
                    sql += ",";
                sql += mapping.getSelfPropertyColumn();
            }

            for(ModelObj modelObj:modelObjList)
            {
                String condItem="";
                for(PropertyMapping mapping:propertyMappings)
                {
                    Object val=modelObj.getEntity(mapping.getJoinPropertyEntity()).get(mapping.getJoinPropertyColumn());
                    if(val instanceof String)
                        val="'"+val.toString()+"'";
                    if (!StringUtils.isEmpty(condItem))
                        condItem += ",";
                    condItem += val;
                }
                conds.add("("+condItem+")");
            }
        }
        String cond="";
        for(String val:conds)
        {
            if(!StringUtils.isEmpty(cond))
                cond += ",";
            cond += val;
        }

        return "("+sql+") in ("+cond+")";
    }
}
