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 cn.ibizlab.util.helper.RuleUtils;
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.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Timestamp;
import java.util.List;

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

    public DataModel getDataModel()
    {
        if(property!=null)
            return property.getOwnerDataModel();
        return null;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public String getDataModelName()
    {
        if(getDataModel()!=null&&getDataModel().getDataModelName()!=null)
            return getDataModel().getDataModelName();
        else
            return "";
    }

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

    public FieldObj setProperty(Property property)
    {
        this.property=property;
        return this;
    }

    private String columnName;

    private  Object value;

    public <T> T getValue(T defaultVal)
    {
        return getValue(null,defaultVal);
    }
    public <T> T getValue(Class<T> type,T defaultVal)
    {
        T ret=defaultVal;
        if(value==null)
            return ret;

        Object obj=null;
        if((!(defaultVal instanceof List))&&(value instanceof List))
        {
            for(Object item:(List)value){
                if(item!=null) {
                    if(obj==null|| RuleUtils.gt(obj,item))
                        obj = item;
                }
            }
            if(obj==null)
                return defaultVal;
        }
        else
        {
            obj=value;
        }

        if(type == null && defaultVal != null)
            type = (Class<T>) defaultVal.getClass();
        ret = DataObject.valueOf(type,obj);
        if(ret==null)
            return defaultVal;
        return ret;
    }

    public <T> T getItemValue(int idx,Class<T> type,T defaultVal)
    {
        if(value instanceof List)
        {
            List list=(List)value;
            if(list.size()>idx)
            {
                T ret=DataObject.valueOf(type,list.get(idx));
                if(ret==null)
                    return defaultVal;
                return ret;
            }
            return defaultVal;
        }
        else
            return getValue(type,defaultVal);
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public String getValues()
    {
        String rt="";
        if(value!=null && value instanceof List)
        {
            for(Object item:(List)value){
                if(item!=null) {
                    if((!StringUtils.isEmpty(rt))&&(!rt.endsWith(",")))
                        rt=rt+",";
                    rt = rt+DataObject.getStringValue(item,"");
                }
            }
        }
        else
        {
            rt=DataObject.getStringValue(value,"");
        }
        return rt;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Integer getCount()
    {
        return getCount(true);
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Integer getCount(boolean includeNull)
    {
        if(includeNull)
        {
            if(value instanceof List)
                return ((List) value).size()==0?1:((List) value).size();
            else
                return 1;
        }
        if(value==null)
            return 0;
        else if(value instanceof List)
        {
            List list = (List)value;
            int cnt=0;
            for(Object item:list)
                cnt+=StringUtils.isEmpty(DataObject.getStringValue(list.get(0),null))?0:1;
            return cnt;
        }
        else
            return StringUtils.isEmpty(value.toString())?0:1;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Boolean isEmpty()
    {
        return getCount(false)==0;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Boolean isNotEmpty()
    {
        return !isEmpty();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Boolean isMultiple()
    {
        return getCount()>1;
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Boolean isSingle()
    {
        return !isMultiple();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public Boolean isSingleAndNotEmpty()
    {
        return isSingle()&&isNotEmpty();
    }

    @JsonIgnore
    @JSONField(serialize = false)
    public BigDecimal getDecimal()
    {
        BigDecimal decimal = new BigDecimal(1);
        Object val = this.getValue(Object.class,null);
        if(val == null)
            decimal=(new BigDecimal(1));
        else if ( (val instanceof BigDecimal))
            decimal=(((BigDecimal) val));
        else if (val instanceof Double)
            decimal=(new BigDecimal((Double) val));
        else if (val instanceof Float)
            decimal=(new BigDecimal(((Float) val).doubleValue()));
        else if (val instanceof Integer)
            decimal=(new BigDecimal((int)val));
        else if (val instanceof Long)
            decimal=(new BigDecimal((Long)val));

        if(decimal.intValue()>Integer.MAX_VALUE)
            decimal=(new BigDecimal(1));

        return decimal;
    }

    public BigDecimal getItemDecimal(int idx)
    {
        BigDecimal decimal = new BigDecimal(1);
        Object val = this.getItemValue(idx,Object.class,null);
        if(val == null)
            decimal=(new BigDecimal(1));
        else if ( (val instanceof BigDecimal))
            decimal=(((BigDecimal) val));
        else if (val instanceof Double)
            decimal=(new BigDecimal((Double) val));
        else if (val instanceof Float)
            decimal=(new BigDecimal(((Float) val).doubleValue()));
        else if (val instanceof Integer)
            decimal=(new BigDecimal((int)val));
        else if (val instanceof Long)
            decimal=(new BigDecimal((Long)val));

        if(decimal.intValue()>Integer.MAX_VALUE)
            decimal=(new BigDecimal(1));

        return decimal;
    }

    @Override
    public String toString()
    {
        return getValues();
    }

    public static void main(String[] args)
    {
        FieldObj fieldObj=new FieldObj();
        fieldObj.setValue(new BigDecimal(1));

        Object t=fieldObj.getValue(Object.class,null);

        System.out.println(t);
    }

}
