package com.neusoft.smart.pos.strategy.service;

import com.neusoft.smart.pos.dto.order.request.PostCreateOrderRequest;
import com.neusoft.smart.pos.framework.exception.BusinessCommonException;
import com.neusoft.smart.pos.framework.utils.SpringUtils;
import com.neusoft.smart.pos.order.constants.TradeErrorCode;
import com.neusoft.smart.pos.dto.order.request.VariableFee;
import com.neusoft.smart.pos.strategy.persistent.domain.BeanTypeDict;
import com.neusoft.smart.pos.strategy.persistent.domain.BeanTypeDictExample;
import com.neusoft.smart.pos.strategy.persistent.domain.ShopOtherChargesConfig;
import com.neusoft.smart.pos.strategy.persistent.domain.ShopOtherChargesConfigExample;
import com.neusoft.smart.pos.strategy.persistent.mapper.BeanTypeDictMapper;
import com.neusoft.smart.pos.strategy.persistent.mapper.ShopOtherChargesConfigMapper;
import com.neusoft.smart.pos.strategy.repository.IStrategy;
import lombok.val;
import net.sf.json.JSONArray;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@Service
public class StrategyService {

    @Resource
    private BeanTypeDictMapper beanTypeDictMapper;

    @Resource
    private ShopOtherChargesConfigMapper shopOtherChargesConfigMapper;

    public void insertBeanTypeDict(BeanTypeDict beanTypeDict) {
        beanTypeDictMapper.insert(beanTypeDict);
    }

    public List<BeanTypeDict> getBeanDictList(String beanType) {
        if(beanType == null) {
            return null;
        }
        val example = new BeanTypeDictExample();
        example.createCriteria().andBeanTypeEqualTo(beanType);
        return beanTypeDictMapper.selectByExample(example);
    }

    // 默认postCreateOrderRequest中的参数都已经经过校正和赋值，如orgId, shopId, orderType等
    public List<VariableFee> doCalculation(PostCreateOrderRequest postCreateOrderRequest) {
        List<VariableFee> variableFeeList = new ArrayList<>();
        List<ShopOtherChargesConfig> shopOtherChargesConfigList = getChargesConfigList(postCreateOrderRequest);
        if(shopOtherChargesConfigList == null || shopOtherChargesConfigList.size() == 0) { //无匹配试算规则
            return variableFeeList;
        }

        for(ShopOtherChargesConfig shopOtherChargesConfig:shopOtherChargesConfigList) {
            VariableFee variableFee = new VariableFee();
            variableFee.setVarFeeName(shopOtherChargesConfig.getDisplayName());
            variableFee.setVarFeeDescription(shopOtherChargesConfig.getDescription());
            variableFee.setVarFeeDiscount(0);

            BeanTypeDict beanType = beanTypeDictMapper.selectByPrimaryKey(shopOtherChargesConfig.getBeanTypeId());
            if(beanType != null) {
                val strategy = SpringUtils.getBean(beanType.getBeanName(), IStrategy.class);
                variableFee.setVarFeeAmount(strategy.doCalculate(postCreateOrderRequest, shopOtherChargesConfig.getBeanParameter()));
            } else {
                variableFee.setVarFeeAmount(0);
            }
            variableFeeList.add(variableFee);
        }
        return variableFeeList;
    }

    private List<ShopOtherChargesConfig> getChargesConfigList(PostCreateOrderRequest postCreateOrderRequest) {
        // 规则：shopId优先匹配，shopId没有匹配项时，再去匹配orgId
        if(postCreateOrderRequest.getShopId() == null ) {
            throw new BusinessCommonException(TradeErrorCode.SHOP_ID_EMPTY);
        }
        val example = new ShopOtherChargesConfigExample();
        example.createCriteria().andShopIdEqualTo(postCreateOrderRequest.getShopId())
                .andOrderTypeEqualTo(postCreateOrderRequest.getOrderType());
        List<ShopOtherChargesConfig> shopOtherChargesConfigList = shopOtherChargesConfigMapper.selectByExample(example);
        if(shopOtherChargesConfigList == null || shopOtherChargesConfigList.size() == 0) {
            if(postCreateOrderRequest.getOrgId() == null ) {
                throw new BusinessCommonException(TradeErrorCode.ORG_ID_EMPTY);
            }
            val configExample = new ShopOtherChargesConfigExample();
            configExample.createCriteria().andOrgIdEqualTo(postCreateOrderRequest.getOrgId())
                    .andOrderTypeEqualTo(postCreateOrderRequest.getOrderType());
            shopOtherChargesConfigList = shopOtherChargesConfigMapper.selectByExample(configExample);
        }
        return shopOtherChargesConfigList;
    }
}
