package com.neusoft.smart.pos.member.core;

import com.alibaba.fastjson.JSONObject;
import com.neusoft.smart.pos.dto.member.request.CheckMemberLevelRequest;
import com.neusoft.smart.pos.member.constants.MemberLevelConditionType;
import com.neusoft.smart.pos.member.dto.MemberLevelConditionTypeResponse;

import java.util.HashMap;
import java.util.Map;

public abstract class MemberLevelCondition {

    private static Map<Integer, ConditionCreator> _conditionTypeMap;

    public static Map<Integer, ConditionCreator> getPolicyClassesMap() {
        if (_conditionTypeMap == null || _conditionTypeMap.size() == 0) {
            _conditionTypeMap = new HashMap<>() ;
            _conditionTypeMap.put(MemberLevelConditionType.RECHARGE_BASED.getCode(), RechargeBasedCondition.getConditionCreator());
            _conditionTypeMap.put(MemberLevelConditionType.AND_OR_GATE.getCode(),AndOrCondition.getConditionCreator());
        }
        return _conditionTypeMap;
    }

    public static MemberLevelCondition createMemberLevelCondition(String jsonPara) {
        JSONObject para = JSONObject.parseObject(jsonPara);
        return getPolicyClassesMap().get(para.getInteger("type")).createInstance(para);
    }

    public static MemberLevelCondition createDefaultMemberLevelCondition(MemberLevelConditionType type) {
        return getPolicyClassesMap().get(type.getCode()).createDefaultInstance();
    }

    public String toJsonString()
    {
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("type", getType().getCode());
        jsonObject.put("condition", getCondition());
        return jsonObject.toJSONString();
    }

    protected abstract JSONObject getCondition();

    protected abstract MemberLevelConditionType getType();

    protected static ConditionCreator getConditionCreator() throws InstantiationException {
        throw new InstantiationException();
    }

    public abstract boolean isMatch(CheckMemberLevelRequest member);

    public abstract static class ConditionCreator {
        abstract MemberLevelCondition createInstance(JSONObject jsonPara);

        abstract MemberLevelConditionType getMemberLevelConditionType();

        public MemberLevelConditionTypeResponse getConditionTypeTag() {
            MemberLevelConditionTypeResponse response = new MemberLevelConditionTypeResponse();
            response.setTypeCode(this.getMemberLevelConditionType().getCode());
            response.setTypeName(this.getMemberLevelConditionType().getValue());
            response.setDemo(this.createDefaultInstance().toJsonString());
            return response;
        }

        public abstract MemberLevelCondition createDefaultInstance();
    }

}
