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


import cn.ibizlab.core.lite.extensions.model.DataModel;
import cn.ibizlab.core.lite.extensions.model.Property;
import cn.ibizlab.util.helper.DataObject;
import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import org.springframework.util.StringUtils;

import java.sql.Timestamp;
import java.util.HashMap;
import java.util.List;

public class EntityObj extends DataObj<String,Object> {

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj copy() {
        EntityObj copy=new EntityObj();
        this.copyTo(copy,true);
        if(this.property!=null)
            copy.setProperty(this.property);
        return copy;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityModel getEntityModel()
    {
        return getProperty().getEntityModel();
    }


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

    @JsonIgnore
    @JSONField(serialize = false)
    private Property property;

    @JsonIgnore
    @JSONField(serialize = false)
    public Property getProperty() {
        return property;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj setProperty(Property property) {
        if(property!=null) {
            if(!StringUtils.isEmpty(property.getSystem()))
                this.setDstSystemId(property.getSystem());
            if(!StringUtils.isEmpty(property.getPropertyEntity()))
                this.setMetaEntityName(property.getPropertyEntity());
            if(!StringUtils.isEmpty(property.getPropertyName()))
                this.setPropertyName(property.getPropertyName());
        }
        this.property = property;
        return this;
    }


    @JsonIgnore
    @JSONField(serialize = false)
    public String getPropertyName()
    {
        return this.getStringValue("_PROPERTYNAME","");
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj setPropertyName(String propertyName)
    {
        return this.set("_PROPERTYNAME",propertyName);
    }


    @JsonIgnore
    @JSONField(serialize = false)
    public String getMetaEntityName()
    {
        return this.getStringValue("_METAENTITYNAME","");
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj setMetaEntityName(String metaEntityName)
    {
        return this.set("_METAENTITYNAME",metaEntityName);
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public String getDstSystemId()
    {
        return this.getStringValue("_DSTSYSTEMID","");
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj setDstSystemId(String dstSystemId)
    {
        return this.set("_DSTSYSTEMID",dstSystemId);
    }

    @Override
	public EntityObj set(String key, Object value)
	{
		return super.set(key,value);
	}

    @JsonIgnore
    @JSONField(serialize = false)
    private ModelObj modelObj;

    @JsonIgnore
    @JSONField(serialize = false)
    public ModelObj getModelObj() {
        return modelObj;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public EntityObj setModelObj(ModelObj modelObj) {
        this.modelObj = modelObj;
        return this;
    }

	@Override
	public String getRowKey()
	{
		String rowKey=super.getRowKey();
		if(StringUtils.isEmpty(rowKey))
		{
			rowKey=this.getStringValue(this.getEntityModel().getKeyField().getColumnName());
			this.setRowKey(rowKey);
		}
		return rowKey;
	}

    @JsonIgnore
    @JSONField(serialize = false)
    @Override
    public Timestamp getTimestamp() {
        Timestamp lastModify=super.getTimestamp();
        if(lastModify.equals(DataObject.getBeginDate())&&this.getEntityModel().getLastModifyField()!=null)
        {
            lastModify=this.getTimestampBegin(this.getEntityModel().getLastModifyField().getColumnName());
            this.setTimestamp(lastModify);
        }
        return super.getTimestamp();
    }

    public void findModel(List<ModelObj> modelObjs)
	{
		HashMap<String, ModelObj> tmps=new HashMap<String, ModelObj>();
		modelObjs.forEach(obj->tmps.put(obj.getRowKey(),obj));
		this.getProperty().getPropertyMappings().forEach(mapping->{
			String selfVal=this.getStringValue(mapping.getSelfPropertyColumn());
			modelObjs.forEach(modelObj->{
				String parentVal=modelObj.getEntity(mapping.getJoinPropertyEntity()).getStringValue(mapping.getJoinPropertyColumn());
				if((StringUtils.isEmpty(parentVal))||(!parentVal.equals(selfVal)))
					tmps.remove(modelObj.getRowKey());
			});
		});
        if(tmps.size()==1)
        {
            tmps.values().iterator().next().setEntity(this.getProperty().getPropertyName(),this);
        }
		else if(tmps.size()>1)
		{
			tmps.values().forEach(obj->{
				obj.setEntity(this.getProperty().getPropertyName(),this.copy());
			});
		}
	}

	public boolean isDelete()
	{
        if(!this.getEntityModel().isLogicValid())
            return false;
        if(this.getEntityModel().getLogicVal().equals(this.get(this.getEntityModel().getLogicValidField().getColumnName())))
            return false;
		return true;
	}
}
