package cn.ibizlab.codegen.model;

import cn.ibizlab.codegen.utils.Inflector;
import cn.ibizlab.codegen.utils.StringAdvUtils;
import com.alibaba.fastjson.JSONObject;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import lombok.experimental.Accessors;
import net.ibizsys.model.dataentity.IPSDataEntity;
import net.ibizsys.model.dataentity.service.*;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

@Getter
@Setter
@NoArgsConstructor
@Accessors(chain = true)
public class ApiMethodModel extends BaseModel {

    private String[] ignoreMethodNames = new String[]{"GET", "CREATE", "UPDATE", "REMOVE"};

    private ApiModel api;

    private ApiEntityModel apiEntity;

    private List<ApiEntityRSModel> parentApiEntities;

    public ApiMethodModel(ApiEntityModel apiEntityModel, List<ApiEntityRSModel> parentApiEntities, IPSDEServiceAPIMethod iPSDEServiceAPIMethod) {
        this.opt = iPSDEServiceAPIMethod;
        this.apiEntity = apiEntityModel;
        this.api = apiEntityModel.getApi();
        this.parentApiEntities = parentApiEntities;
        this.setCodeName(iPSDEServiceAPIMethod.getCodeName());
        this.setName(iPSDEServiceAPIMethod.getName());
    }

    public IPSDEServiceAPIMethod getPSDEServiceAPIMethod() {
        return (IPSDEServiceAPIMethod) opt;
    }

    public String getMethodName() {
        String strName = super.getName();
        if (CollectionUtils.isNotEmpty(parentApiEntities)) {
            strName += "By";
            for (ApiEntityRSModel parent : parentApiEntities) {
                strName += StringAdvUtils.pascalcase(parent.getParentIdFieldCodeName());
            }
        }
        return strName;
    }

    public String getRequestPath() {
        String path = "";
        if (!CollectionUtils.isEmpty(parentApiEntities)) {
            for (ApiEntityRSModel apiRs : parentApiEntities) {
                String strMajorEntityPlurlize = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(apiRs.getMajorEntityCodeName()).toLowerCase());
                path = String.format("/%s/{%s}", strMajorEntityPlurlize, StringAdvUtils.camelcase(apiRs.getParentIdFieldCodeName())) + path;
            }
        }

        //主键
        String strPlurlize = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(apiEntity.getCodeName()).toLowerCase());
        if (getPSDEServiceAPIMethod().isNeedResourceKey()) {
            path = path + String.format("/%s/{%s}", strPlurlize, StringAdvUtils.camelcase(apiEntity.getEntity().getKeyField().getCodeName()));
        } else {
            path = path + String.format("/%s", strPlurlize);
        }

        //方法名
        if (!ArrayUtils.contains(ignoreMethodNames, this.getName().toUpperCase())) {
            path = path + String.format("/%s", this.getName().toLowerCase());
        }

        return path;
    }

    public List getPathVariables() {
        List pathVariables = new ArrayList();
        if (!CollectionUtils.isEmpty(parentApiEntities)) {
            for (ApiEntityRSModel apiRs : parentApiEntities) {
                String strMajorEntityPlurlize = Inflector.getInstance().pluralize(StringAdvUtils.camelcase(apiRs.getMajorEntityCodeName()).toLowerCase());
                JSONObject pathVariable = new JSONObject();
                pathVariable.put("name", apiRs.getParentIdFieldCodeName());
                pathVariable.put("type", PropType.findType(apiRs.getParentIdFieldType()));
                pathVariables.add(0, pathVariable);
            }
        }
        if (getPSDEServiceAPIMethod().isNeedResourceKey()) {
            JSONObject pathVariable = new JSONObject();
            pathVariable.put("name", apiEntity.getEntity().getKeyField().getCodeName());
            pathVariable.put("type", apiEntity.getEntity().getKeyField().getType());
            pathVariables.add(pathVariable);
        }
        return pathVariables;
    }

    public String getBody() {
        IPSDEServiceAPIMethodInput iPSDEServiceAPIMethodInput = getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
        if (iPSDEServiceAPIMethodInput != null) {
            if ("DTO".equals(iPSDEServiceAPIMethodInput.getType())) {
                if ("DEFAULT".equals(iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getType()))
                    return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName();
                else if ("DEFILTER".equals(iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getType()))
                    return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName().replace("FilterDTO", "SearchContext");
            } else if ("DTOS".equals(iPSDEServiceAPIMethodInput.getType())) {
                    return iPSDEServiceAPIMethodInput.getPSDEMethodDTO().getName();
            } else if ("KEYFIELD".equals(iPSDEServiceAPIMethodInput.getType())
                    && getPSDEServiceAPIMethod().getPSDEAction()!=null
                    && getPSDEServiceAPIMethod().getPSDEAction().getActionType().equals("USERCUSTOM")) {
                return apiEntity.getCodeName() + "DTO";
            }
        }
        return null;
    }

    public IPSDEServiceAPIMethodInput getInput() {
        return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodInput();
    }

    public IPSDEServiceAPIMethodReturn getReturn() {
        return getPSDEServiceAPIMethod().getPSDEServiceAPIMethodReturn();
    }


}
