package cn.ibizlab.codegen.model;

import com.alibaba.fastjson.annotation.JSONField;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.dataentity.defield.IPSDEField;

import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;

import cn.ibizlab.codegen.utils.StringAdvUtils;

import java.security.Timestamp;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
@JsonIgnoreProperties(value = "handler")
public class FieldModel extends BaseModel {

    public FieldModel(EntityModel entityModel,IPSDEField deField)
    {
        this.opt=deField;
        this.entity=entityModel;
        this.setCodeName(deField.getCodeName());
        this.setName(deField.getName());
        this.setId(String.format("%1$s-%2$s",entity.getCodeName(),deField.getCodeName()));
    }


    public String getFieldName() {
        return getDataEntityField().getName();
    }

    public String getColumnName() {
        return getFieldName().toLowerCase();
    }

    public String getAlias() {
        String alias=StringAdvUtils.camelcase(this.getCodeName());
        return getColumnName().equalsIgnoreCase(alias)&&(!"PICKUP".equals(getDataEntityField().getDataType()))?null:alias;
    }

    public String getJsonName() {
        return getDataEntityField().getCodeName().toLowerCase();
    }

    private String format;
    private String timeType;

    public String getTimeType()
    {
        getFormat();
        return timeType;
    }

    public String getFormat(){
        if("Timestamp".equals(getType().getJava())&&StringUtils.isEmpty(format))
        {
            if(getDataEntityField().getDataType().equals("DATE")||"%1$tY-%1$tm-%1$td".equalsIgnoreCase(getDataEntityField().getValueFormat())){
                timeType="DATE";
                format = "yyyy-MM-dd";
            }
            else if(getDataEntityField().getDataType().equals("TIME")||"%1$tH:%1$tM:%1$tS".equalsIgnoreCase(getDataEntityField().getValueFormat())){
                timeType="TIME";
                format = "HH:mm:ss";
            }
            else{
                timeType="DATETIME";
                format = "yyyy-MM-dd HH:mm:ss";
            }   
        }
        return format;
    }

    public boolean isDeepStructure()
    {
        return "ONE2MANYDATA".equalsIgnoreCase(getDataEntityField().getDataType());
    }

    public boolean isEnableAudit()
    {
        return getDataEntityField().isEnableAudit()&&this.getEntity().getDataEntity()!=null&&this.getEntity().getDataEntity().getAuditMode()!=0;
    }

    public String getAnnotation()
    {
        String annotation="name = \""+getFieldName().toLowerCase()+"\"";
        if(!StringUtils.isEmpty(getDataEntityField().getDefaultValue()))
            annotation+=" , defaultValue = \""+getDataEntityField().getDefaultValue()+"\"";
        if(!StringUtils.isEmpty(getDataEntityField().getDefaultValueType()))
            annotation+=" , defaultValueType = DEFieldDefaultValueType."+getDataEntityField().getDefaultValueType().toUpperCase();
        if(isKeyDEField())
            annotation+=" , isKeyField = true";
        if(!StringUtils.isEmpty(getDataEntityField().getPredefinedType()))
            annotation+=" , preType = DEPredefinedFieldType."+getDataEntityField().getPredefinedType().toUpperCase();
        if(isLogicValidField()){
            annotation+=" , logicval = \""+getEntity().getValidLogicValue()+"\"";
            annotation+=" , logicdelval = \""+getEntity().getInvalidLogicValue()+"\"";
        }
        if(!StringUtils.isEmpty(dict))
            annotation+=" , dict = \""+dict+"\"";
        if("ALL".equalsIgnoreCase(getDataEntityField().getDupCheckMode()))
        {
            annotation+=" , dupCheck = DupCheck.ALL";
            if(!ObjectUtils.isEmpty(getDataEntityField().getDupCheckPSDEFields()))
            {
                List<String> dups=new ArrayList<>();
                for(IPSDEField dup:getDataEntityField().getDupCheckPSDEFields()){
                    dups.add(StringAdvUtils.camelcase(dup.getCodeName()));
                }
                if(dups.size()>0)
                    annotation+=" , dupCheckField = \""+String.join(",", dups)+"\"";
            }
        }
        if(isEnableAudit()&&getFormat()!=null)
            annotation+=" , fieldType = \""+timeType+"\", format = \""+format+"\"";
        if(getDataEntityField().isMultiFormDEField() &&  getEntity().getDataEntity()!=null && (getEntity().getDataEntity().getDynaInstMode()==1||getEntity().getDataEntity().getDynaInstMode()==1))
            annotation+=" , dynaInstTagField = true";
        
        return annotation;
    }

    public String getLogicName() {
        return getDataEntityField().getLogicName();
    }

    public PropType getType()
    {
        return PropType.findType(this.getDataEntityField().getStdDataType());
    }

    private String expression;

    private String dict;

    public IPSDEField getDataEntityField()
    {
        return (IPSDEField)opt;
    }

    private EntityModel entity;

    private RelationshipModel reference;

    private String refFieldName;

    private String refFieldCodeName;

    public boolean isPhisicalDEField()
    {
        return this.getDataEntityField().isPhisicalDEField();
    }

    public boolean isKeyDEField()
    {
        return this.getDataEntityField().isKeyDEField();
    }

    public boolean isLogicValidField()
    {
        return "LOGICVALID".equals(this.getDataEntityField().getPredefinedType());
    }

    public boolean isLastModifyField()
    {
        return "UPDATEDATE".equals(this.getDataEntityField().getPredefinedType());
    }

    public boolean isCreateTimeField()
    {
        return "CREATEDATE".equals(this.getDataEntityField().getPredefinedType());
    }

    public boolean isInsertOnly()
    {
        return "CREATEDATE".equals(this.getDataEntityField().getPredefinedType())||"CREATEMAN".equals(this.getDataEntityField().getPredefinedType());
    }

    public boolean isOrgField()
    {
        return "ORGID".equals(this.getDataEntityField().getPredefinedType());
    }

    public boolean isUnionKeyField()
    {
        return !StringUtils.isEmpty(this.getDataEntityField().getUnionKeyValue());
    }

    public String getDefaultValue()
    {
        if((!StringUtils.isEmpty(getDataEntityField().getDefaultValueType()))||(!StringUtils.isEmpty(getDataEntityField().getDefaultValue())))
        {
            String defaultValue="";
            if(StringUtils.isEmpty(getDataEntityField().getDefaultValueType())||"NONE".equalsIgnoreCase(getDataEntityField().getDefaultValueType()))
            {
                defaultValue=getDataEntityField().getDefaultValue();
            }
            else if(!StringUtils.isEmpty(getDataEntityField().getDefaultValue()))
            {
                defaultValue= String.format("${%1$s.%2$s}",getDataEntityField().getDefaultValueType(),getDataEntityField().getDefaultValue());
            }
            else
            {
                defaultValue= String.format("${%1$s}",getDataEntityField().getDefaultValueType());
            }
            return defaultValue;
        }
        return null;
    }

    public Set<String> getSearchMode()
    {
        Set<String> modes=new LinkedHashSet<>();
        if(getDataEntityField().getAllPSDEFSearchModes()!=null)
        {
            getDataEntityField().getAllPSDEFSearchModes().forEach(item->modes.add(item.getValueOP().toLowerCase()));
        }
        if(getDataEntityField().isEnableQuickSearch())
            modes.add("query");
        return modes;
    }



    public String getStringValue(String key,String defaultVal)
    {
        return extParams.getStringValue(key,defaultVal);
    }

    public String getColumnName(String dsType)
    {
        return this.getStringValue("column-"+dsType.toLowerCase(),getFieldName());
    }





}
