package com.brilliance.mda.runtime.response;

import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import com.brilliance.mda.runtime.mda.IContext;
import com.brilliance.mda.runtime.mda.driver.MdaDriver;
import com.brilliance.mda.runtime.mda.driver.MdaEnv;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonInclude;

@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class ResponseSet<T> {

    /**
     * 成功代码
     */
    public static final String CODE_SUCCESS="AAAAAA";
    public static final String MSG_SUCESS="操作成功！";

    private String respCode;
    private String respMsg;
    private Map<String,String> fieldErrors;
    private Map<String, List<String>> codeSet;
    private Object data;

    public ResponseSet(IContext ctx, Object t){
        this.respCode = CODE_SUCCESS;
        this.respMsg = MSG_SUCESS;
        this.data = t;
        fieldErrors = cloneFieldErrorsFromContext(ctx);
        this.codeSet = getValuesSet(ctx);
        ctx.visitValues();
        MdaDriver.setValueToVO(ctx, this.data);
    }
    private Map<String, List<String>> getValuesSet(IContext ctx){
        Map<String, List<String>> valuesSet = new LinkedHashMap<>();
        ctx.getValuesSet().forEach((key, codeEntity)->{
            if(!codeEntity.visited){
                valuesSet.put(key,codeEntity.values);
            }
        });
        return valuesSet;
    }

    private Map<String,String> cloneFieldErrorsFromContext(IContext ctx){
        if(ctx == null){
            return null;
        }
        Map<String,String> fieldErrors = ctx.getFieldErrors();
        Map<String,String> fieldErrorsClone = new LinkedHashMap<>();
        fieldErrorsClone.putAll(fieldErrors);
        fieldErrors.clear();
        return fieldErrorsClone;
    }

    public ResponseSet(Object t){
        this.respCode = CODE_SUCCESS;
        this.respMsg = MSG_SUCESS;
        if(MdaEnv.getContext()!=null) {
            fieldErrors = cloneFieldErrorsFromContext(MdaEnv.getContext());
            this.codeSet = getValuesSet(MdaEnv.getContext());
            MdaEnv.getContext().visitValues();
        }
        this.data = t;
    }

    public ResponseSet(String errCode,String errMsg){
        this.respCode = errCode;
        this.respMsg = errMsg;
        if(MdaEnv.getContext()!=null) {
            fieldErrors = cloneFieldErrorsFromContext(MdaEnv.getContext());
            this.codeSet = getValuesSet(MdaEnv.getContext());
            MdaEnv.getContext().visitValues();
        }
    }

    //    public ResponseSet(String errCode,String errMsg,Map<String,String> fieldErrors){
//        this(errCode,errMsg);
//        this.fieldErrors = fieldErrors;
//    }
    public ResponseSet(String errCode,String errMsg,T t){
        this(errCode,errMsg);
        this.data = t;
        if(t!=null) {
            MdaDriver.setValueToVO(MdaEnv.getContext(), this.data);
        }
    }
    public Object getData() {
        return data;
    }
    public void setData(Object data) {
        this.data = data;
    }

    public String getRespCode() {
        return respCode;
    }

    public void setRespCode(String respCode) {
        this.respCode = respCode;
    }

    public String getRespMsg() {
        return respMsg;
    }

    public void setRespMsg(String respMsg) {
        this.respMsg = respMsg;
    }

    public Map<String, String> getFieldErrors() {
        return fieldErrors;
    }

    public void setFieldErrors(Map<String, String> fieldErrors) {
        this.fieldErrors = fieldErrors;
    }

    public Map<String, List<String>> getCodeSet() {
        return codeSet;
    }

    public void setCodeSet(Map<String, List<String>> codeSet) {
        this.codeSet = codeSet;
    }

    static class BooleanResult{
        boolean result;
        public BooleanResult(boolean result){
            this.result = result;
        }
    }
    static final String FAIL_CODE = "999999";
    public static ResponseSet fail(String message) {
        ResponseSet responseSet = new ResponseSet(FAIL_CODE,message);
        return responseSet;
    }
    public static ResponseSet simpleSuccess(Object data){
        return new ResponseSet(data);
    }

}
