package cn.com.qmth.stmms.ms.marking.service;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import cn.com.qmth.stmms.ms.core.domain.Level;
import cn.com.qmth.stmms.ms.core.domain.task.MarkTask;
import cn.com.qmth.stmms.ms.core.domain.user.MarkUser;
import cn.com.qmth.stmms.ms.core.repository.LevelRepo;
import cn.com.qmth.stmms.ms.core.repository.MarkUserRepo;

/**
 * 定档
 * Created by zhengmin on 2016/9/22.
 */
@Service
public class DetermineLevelService {

    public enum DeterType{
        /**
         * 多数
         */
        MAJORITY,
        /**
         * 权重
         */
        WEIGHT
    }

    @Autowired
    private LevelRepo levelRepo;
    @Autowired
    private MarkUserRepo markUserRepo;

    public DeterResult determine(boolean majority,MarkTask...tasks){
    	if(majority){
    		//如果相同的数量大于半数，直接定档
    		Stream<MarkTask> taskStream = Stream.of(tasks);
    		Optional<Map.Entry<String,Long>> optional = taskStream
    				.collect(Collectors.groupingBy(i -> i.getResult().toString(), Collectors.counting()))
    				.entrySet()
    				.stream()
    				.max(Comparator.comparing(Map.Entry::getValue));
    		if(optional.isPresent()){
    			Map.Entry<String,Long> entry = optional.get();
    			if(entry.getValue() > tasks.length/2){
    				return new DeterResult(entry.getKey(),DeterType.MAJORITY);
    			}
    		}
    	}
        //通过权重计算，平均值四舍五入
        double[] values = new double[tasks.length];
        double[] weights = new double[tasks.length];
        Long workId = null;
        for (int i = 0; i < tasks.length; i++) {
            workId = tasks[i].getWorkId();
            Level level = levelRepo.findByWorkIdAndCode(workId,String.valueOf(tasks[i].getResult()));
            if(level == null){
                throw new RuntimeException("无此档位");
            }
            MarkUser marker = markUserRepo.findOne(tasks[i].getMarkerId());
            double markerWeight = marker.getWeight();
            values[i] = level.getWeight()*markerWeight;
            weights[i] = markerWeight;
        }
        int avg = (int)Math.round(DoubleStream.of(values).sum()/DoubleStream.of(weights).sum());
        List<Level> levels = levelRepo.findByWorkId(workId);
        Optional<Level> levelOptional = levels.stream().filter(o -> o.getMaxScore() >= avg && o.getMinScore() <= avg).findFirst();
        Level level = levelOptional.orElse(null);
        if(level == null){
        	levels = levels.stream().sorted(Comparator.comparing(Level::getMaxScore).reversed()).collect(Collectors.toList());
        	if(avg>levels.get(0).getMaxScore()){
        		level = levels.get(0);
        	}
        	levels = levels.stream().sorted(Comparator.comparing(Level::getMinScore)).collect(Collectors.toList());
        	if(avg<levels.get(0).getMinScore()){
        		level = levels.get(0);
        	}
        }
        return new DeterResult(level.getCode(),DeterType.WEIGHT);
    }
}

class DeterResult{
    private String result;
    private DetermineLevelService.DeterType deterType;

    public DeterResult(String result, DetermineLevelService.DeterType deterType) {
        this.result = result;
        this.deterType = deterType;
    }

    public String getResult() {
        return result;
    }

    public void setResult(String result) {
        this.result = result;
    }

    public DetermineLevelService.DeterType getDeterType() {
        return deterType;
    }

    public void setDeterType(DetermineLevelService.DeterType deterType) {
        this.deterType = deterType;
    }
}