package com.rf.psychological.plan.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.rf.psychological.dao.model.CognitiveTaskEntity;
import com.rf.psychological.scale.dao.model.SubjectEntity;
import com.rf.psychological.user.dao.model.UserEntity;
import com.rf.psychological.user.dao.repository.UserRepository;
import com.rf.psychological.plan.dao.dto.TestPlanUserDto;
import com.rf.psychological.plan.dao.model.TestPlanContendEntity;
import com.rf.psychological.plan.dao.model.TestPlanEntity;
import com.rf.psychological.plan.dao.model.TestPlanUserEntity;
import com.rf.psychological.plan.dao.repository.TestPlanContendRepository;
import com.rf.psychological.plan.dao.repository.TestPlanRepository;
import com.rf.psychological.plan.dao.repository.TestPlanUserRepository;
import com.rf.psychological.plan.service.TestPlanService;
import com.rf.psychological.scale.dao.repository.CognitiveTaskRepository;
import com.rf.psychological.scale.dao.repository.SubjectRepository;
import com.rf.psychological.utils.HttpStatus;
import com.rf.psychological.utils.Result;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.Predicate;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author lpf
 * @description:
 * @date 2022/1/614:35
 */
@Service
public class TestPlanServiceImpl implements TestPlanService {

    @Autowired
    private TestPlanRepository testPlanRepository;

    @Autowired
    private TestPlanUserRepository testPlanUserRepository;

    @Autowired
    private TestPlanContendRepository testPlanContendRepository;

    @Autowired
    private CognitiveTaskRepository cognitiveTaskRepository;

    @Autowired
    private SubjectRepository subjectRepository;

    @Autowired
    private UserRepository userRepository;

    @Override
    public Page<TestPlanEntity> findAllByInstitutionNo(String institutionNo, String searchKey, Date beginTime, Date endTime, String status, int beginNum, int pageNum) {
        Specification<TestPlanEntity> specification = (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            predicateList.add(cb.equal(root.get("institutionNo"),institutionNo));
            if(StringUtils.isNotBlank(searchKey)){
                predicateList.add(cb.like(root.get("name"),"%"+searchKey+"%"));
            }
            if(StringUtils.isNotBlank(status)){
                predicateList.add(cb.equal(root.get("status"),status));
            }
            if(beginTime != null ){
                predicateList.add(cb.greaterThanOrEqualTo(root.get("testBeginTime"),beginTime));
            }
            if(endTime != null){
                predicateList.add(cb.lessThanOrEqualTo(root.get("testEndTime"),endTime));
            }
            query.where(cb.and(predicateList.toArray(new Predicate[0])));
            return query.getRestriction();
        };
        return  this.testPlanRepository.findAll(specification, PageRequest.of(beginNum-1,pageNum));
    }

    @Override
    public TestPlanEntity findAllById(String id, String searchKey, Date beginTime, Date endTime, String status) {
        return testPlanRepository.findAllById(id, searchKey, beginTime, endTime, status);
    }

    @Override
    public void updateStatus(String id, int status) {
        testPlanRepository.updateStatus(id, status);
    }

    @Override
    public void updateInfo(String id, String name, Date beginTestTime, Date endTestTime) {
        testPlanRepository.updateInfo(id, name, beginTestTime, endTestTime);
    }

    @Override
    public void save(TestPlanEntity testPlanEntity) {
        testPlanRepository.save(testPlanEntity);
    }

    @Override
    public void deleteById(String id) {
        testPlanRepository.deleteById(id);
    }

    @Override
    public void saveInBatch(List<TestPlanEntity> testPlanEntity) {
        testPlanRepository.saveAll(testPlanEntity);
    }

    @Override
    @Transactional(readOnly = true, rollbackFor = Exception.class)
    public Result getSubCogInfo(String flag, String type) {
        JSONObject jsonObject = new JSONObject();
        if (type.equals("0")) {
            List<SubjectEntity> subjectByFlag = subjectRepository.getSubjectByFlag(flag);
            jsonObject.put("data", subjectByFlag.get(0));
        } else if (type.equals("1")) {
            CognitiveTaskEntity byTaskCode = cognitiveTaskRepository.findByTaskCode(flag);
            jsonObject.put("data", byTaskCode);
        }
        return new Result<>(HttpStatus.SUCCESS, "成功", jsonObject);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public List<TestPlanUserDto> getTestPlanInUser(List<TestPlanUserEntity> testPlanUserEntities, String searchKey, Date beginTime, Date endTime, String userId, String status) {
        ArrayList<TestPlanUserDto> testPlanUserDtos = new ArrayList<>();
        if (!testPlanUserEntities.isEmpty()) {
            for (TestPlanUserEntity testPlanUserEntity : testPlanUserEntities) {
                TestPlanUserDto testPlanUserDto = new TestPlanUserDto();
                TestPlanEntity allById = testPlanRepository.findAllById(testPlanUserEntity.getTestPlanId(), searchKey, beginTime, endTime, status);
                if (allById != null) {
                    //查看测试计划内总数量
                    TestPlanContendEntity keyTestPlanId = new TestPlanContendEntity();
                    keyTestPlanId.setTestPlanId(testPlanUserEntity.getTestPlanId());
                    //测试计划的任务总数
                    long allNum = testPlanContendRepository.count(Example.of(keyTestPlanId));
                    //查看当前用户是否完成当前测试计划
                    UserEntity one = userRepository.getOne(userId);
                    //当前计划用户已完成的任务书
                    int doNum = testPlanContendRepository.getUserDoTestPlanNum(one.getInstitutionNo(), one.getPhone(), testPlanUserEntity.getTestPlanId());
                    BeanUtils.copyProperties(allById, testPlanUserDto);
                    testPlanUserDto.setIsComplete(testPlanUserEntity.getIsComplete());
                    testPlanUserDto.setAllContendsNum(String.valueOf(allNum));
                    testPlanUserDto.setCompleteNum(String.valueOf(doNum));
                    testPlanUserDtos.add(testPlanUserDto);
                }
            }

        }
            return testPlanUserDtos;
    }

    @Override
    public List<TestPlanEntity> findall() {
        return this.testPlanRepository.findAll();
    }

    @Override
    public TestPlanEntity findById(String planId) {
        return this.testPlanRepository.findById(planId).orElse(null);
    }

    @Override
    public List<TestPlanEntity> findByPlanId(List<String> planIds, List<Integer> status) {
        Specification<TestPlanEntity> specification = (Specification<TestPlanEntity>) (root, query, cb) -> {
            List<Predicate> predicateList = new ArrayList<>();
            if (planIds != null && planIds.size() > 0) {
                List<Predicate> predicateListGroupId = new ArrayList<>();
                CriteriaBuilder.In<String> cbGroupId = cb.in(root.get("id"));
                planIds.forEach(cbGroupId::value);
                predicateListGroupId.add(cbGroupId);
                predicateList.add(cb.and(predicateListGroupId.toArray(new Predicate[0])));
            }
            if (status != null && status.size() > 0) {
                List<Predicate> predicateListStatus = new ArrayList<>();
                CriteriaBuilder.In<Integer> cbStatus = cb.in(root.get("status"));
                status.forEach(cbStatus::value);
                predicateListStatus.add(cbStatus);
                predicateList.add(cb.and(predicateListStatus.toArray(new Predicate[0])));
            }
            query.where(cb.and(predicateList.toArray(new Predicate[predicateList.size()])));
            return query.getRestriction();
        };
        return  this.testPlanRepository.findAll(specification);
    }

    /**
     * 到达开始时间未开始的测试计划
     * 到达结束时间未结束的测试计划
     */
    @Override
    public List<TestPlanEntity> findPlan() {

        return this.testPlanRepository.findPlan();
    }

    /**
     * 批量删除
     *
     * @param deleteEntryList 删除列表
     */
    @Override
    public void deleteInBatch(List<TestPlanEntity> deleteEntryList) {
        this.testPlanRepository.deleteInBatch(deleteEntryList);
    }

    @Override
    public List<TestPlanEntity> findAllByInstitutionNo(String institutionNo) {
        return testPlanRepository.findAllByInstitutionNo(institutionNo);
    }


}