package com.tykj.dev.device.questionbank.service.impl;

import com.fasterxml.jackson.core.type.TypeReference;
import com.github.wenhao.jpa.PredicateBuilder;
import com.github.wenhao.jpa.Specifications;
import com.tykj.dev.device.questionbank.dao.ProblemDao;
import com.tykj.dev.device.questionbank.entity.Problem;
import com.tykj.dev.device.questionbank.entity.vo.ProblemPageVo;
import com.tykj.dev.device.questionbank.service.ProblemService;
import com.tykj.dev.misc.exception.ApiException;
import com.tykj.dev.misc.utils.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;

@Service
public class ProblemServiceImpl implements ProblemService {

    @Autowired
    ProblemDao problemDao;

    @Override
    public Problem saveProble(Problem problem) {
        if (problem.getProblemType()==1||problem.getProblemType()==4){
            problem.setChooseOptions(JacksonUtil.toJSon(problem.getChooseOptionsList()));
        }
        return problemDao.save(problem);
    }

    @Override
    public Problem findByIdProble(Integer id) {
        Optional<Problem> optional = problemDao.findById(id);
        if (optional.isPresent()){
           return optional.get();
        }else {
            throw new ApiException(ResponseEntity.status(500).body("[题目] 没有找到对应的题目"));
        }

    }

    @Override
    public List<Problem> findByTypeAndLevel(Integer type, Integer level) {
        return problemDao.findAllByProblemTypeAndProblemLevel(type,level);
    }

    @Override
    public List<Problem> findAll() {
        return problemDao.findAll();
    }

    @Override
    public void deleteById(Integer id) {
        problemDao.updateDeleteTagById(id);
    }

    @Override
    public void deleteByIds(List<Integer> ids) {
        problemDao.updateDeleteTag(ids);
    }

    @Override
    public Page<Problem> pageProblemSelect(ProblemPageVo problemPageVo) {
        return problemDao.findAll(getProblemSpecification(problemPageVo),problemPageVo.getPageable()).map(problem -> {
            if (problem.getChooseOptions()!=null){
                problem.setChooseOptionsList(JacksonUtil.readValue(problem.getChooseOptions(), new TypeReference<List<String>>() {
                }));
            }
            return problem;
        });
    }

    @Override
    public Map<Integer, Map<Integer,Integer>> getProblemCount() {
        Map<Integer,Map<Integer,Integer>> map=new HashMap<>();
        Map<String,Integer> stringIntegerMap=new HashMap<>();
        problemDao.findAll().forEach(
          problem -> {
              String key=problem.getProblemType()+","+problem.getProblemLevel();
              if (stringIntegerMap.containsKey(key)){
                  stringIntegerMap.put(key,stringIntegerMap.get(key)+1);
              }else {
                  stringIntegerMap.put(key,1);
              }
          }
        );

        stringIntegerMap.forEach((k,v)->{
            String [] strings= k.split(",");
            Integer type= Integer.parseInt(strings[0]);
            Integer level= Integer.parseInt(strings[1]);
                    if (map.containsKey(type)){
                       Map<Integer,Integer> levelMap=  map.get(type);
                        levelMap.put(level,v);
                       map.put(type,levelMap);
                    }else {
                        Map<Integer,Integer> levelMap=  new HashMap<>();
                        levelMap.put(level,v);
                        map.put(type,levelMap);
                    }
        });

       return map;
    }


    private Specification<Problem> getProblemSpecification(ProblemPageVo problemPageVo) {
        PredicateBuilder<Problem> predicateBuilder = Specifications.and();
        if (problemPageVo!=null){
            if (problemPageVo.getDesDim()!=null){
                predicateBuilder.like("des","%"+problemPageVo.getDesDim()+"%");
            }
            if (problemPageVo.getLevel()!=null){
                predicateBuilder.eq("problemLevel",problemPageVo.getLevel());
            }
            if (problemPageVo.getType()!=null){
                predicateBuilder.eq("problemType",problemPageVo.getType());
            }
        }
        return predicateBuilder.build();

    }
}
