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

import com.neusoft.smart.pos.dto.printer.response.*;
import com.neusoft.smart.pos.framework.utils.ListUtils;
import com.neusoft.smart.pos.framework.utils.SpringUtils;
import com.neusoft.smart.pos.printer.persistent.domain.*;
import com.neusoft.smart.pos.printer.persistent.ext.domain.Printer;
import com.neusoft.smart.pos.printer.persistent.ext.domain.PrinterObject;
import com.neusoft.smart.pos.printer.repository.IPrinterRuleRepository;
import com.neusoft.smart.pos.printer.repository.PrinterRuleRefRepository;
import com.neusoft.smart.pos.printer.repository.PrinterRuleRepository;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

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

@Service("printerRuleService")
public class PrinterRuleService {

	@Autowired
	private PrinterRuleRefRepository printerRuleRefRepository;

	@Autowired
	private PrinterRuleRepository printerRuleRepository;

	/**
	 * 打印规则执行方法
	 * @return
	 */
	public void executeRule(Integer orgId,Integer shopId,PrinterObject printerObject) {
		List<Printer> printers = new ArrayList<>();
		//1.查询规则关系列表数据
		for(int i=0;i<printerObject.getPrinterTarget().getPrinters().size();i++){
			Printer printer = printerObject.getPrinterTarget().getPrinters().get(i);
			List<PrinterRuleRef> printerRuleRefs = printerRuleRefRepository.queryPrinterRulesByPrinterId(printer.getPrinterId());
			if(printers.size() == 0){
				printers = executeRuleHandle(printerRuleRefs,orgId,shopId,printer);
			}else{
				printers.addAll(executeRuleHandle(printerRuleRefs,orgId,shopId,printer));
			}
		}
		printerObject.getPrinterTarget().setPrinters(printers);
	}
	
	/**
	 * 遍历规则列表，执行规则返回打印任务列表数据
	 * @param printerRuleRefs
	 * @param orgId
	 * @param shopId
	 * @param printer
	 * @return
	 */
	private List<Printer> executeRuleHandle(List<PrinterRuleRef> printerRuleRefs,Integer orgId,Integer shopId,Printer printer){
		List<Printer> printerList = new ArrayList<>();
		for(int i=0;i<printerRuleRefs.size();i++){
			//如果已执行最后一个规则，则直接返回
			if(i==0){
				printerList.addAll(printerRuleHandle(orgId,shopId,printer,printerRuleRefs.get(i)));
			}else{
				List<Printer> printerTempList = new ArrayList<>();
				for(int j=0;j<printerList.size();j++){
					printerTempList.addAll(printerRuleHandle(orgId,shopId,printerList.get(j),printerRuleRefs.get(i)));
				}
				printerList.clear();
				printerList.addAll(printerTempList);
			}
		}
		return printerList;
	}
	
	/**
	 * 规则执行方法
	 * @param orgId
	 * @param shopId
	 * @param printer
	 * @return
	 */
	private List<Printer> printerRuleHandle(Integer orgId,Integer shopId,Printer printer,PrinterRuleRef printerRuleRef){
		PrinterRule printerRule = printerRuleRepository.queryPrinterRulesByRuleId(printerRuleRef.getRuleId());
		val printerRuleRepository = SpringUtils.getBean(printerRule.getBeanName(),IPrinterRuleRepository.class);
		return printerRuleRepository.executeRule(orgId,shopId,printer,printerRule.getId(),printerRuleRef.getId());
	}
	
	/**
	 * 打印规则字典列表查询方法
	 * @return
	 */
	public GetPrinterRulesResponse queryPrinterRules(String isEnable) {
		GetPrinterRulesResponse printerRulesResponse = new GetPrinterRulesResponse();
		
		//1.查询规则列表信息
		List<PrinterRule> printerRuleList = printerRuleRepository.queryPrinterRuleList(isEnable);
		List<GetPrinterRuleResponse> printerRuleResponseList = ListUtils.convertListToList(printerRuleList, GetPrinterRuleResponse.class);
		printerRuleResponseList.forEach(printerRule->{
			//2.查询规则属性列表信息
			List<RuleAttribute> ruleAttributeList = printerRuleRepository.queryPrinterRuleAttributeList(printerRule.getId());
			List<GetPrinterRuleAttributeResponse> printerRuleAttributeResponseList = ListUtils.convertListToList(ruleAttributeList, GetPrinterRuleAttributeResponse.class);
			printerRuleAttributeResponseList.forEach(printerRuleAttribute->{
				//3.查询规则属性值列表信息
				List<RuleAttributeValue> ruleAttributeValueList = printerRuleRepository.queryPrinterRuleAttributeValueList(printerRuleAttribute.getId());
				List<GetPrinterRuleAttributeValueResponse> printerRuleAttributeValueResponseList = ListUtils.convertListToList(ruleAttributeValueList, GetPrinterRuleAttributeValueResponse.class);
				printerRuleAttribute.setPrinterRuleAttributeValueList(printerRuleAttributeValueResponseList);
			});
			printerRule.setPrinterRuleAttributeList(printerRuleAttributeResponseList);
		});
		printerRulesResponse.setPrinterRuleList(printerRuleResponseList);
		return printerRulesResponse;
	}
}
