package com.tykj.dev.device.user.subject.service.impl;

import com.tykj.dev.device.user.base.ret.*;
import com.tykj.dev.device.user.subject.dao.MgrcertDao;
import com.tykj.dev.device.user.subject.dao.UserDao;
import com.tykj.dev.device.user.subject.entity.Mgrcert;
import com.tykj.dev.device.user.subject.entity.Units;
import com.tykj.dev.device.user.subject.entity.User;
import com.tykj.dev.device.user.subject.service.UnitsService;
import com.tykj.dev.device.user.subject.service.UserService;
import com.tykj.dev.misc.utils.JacksonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zjm
 * @version 1.0.0
 * @ClassName UserServiceImpl.java
 * @Description 用户逻辑层
 * @createTime 2020年07月27日 15:07:00
 */
@Service
public class UserServiceImpl implements UserService {
    @Autowired
    UserDao userDao;
    @Autowired
    BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    MgrcertDao mgrcertDao;
    @Autowired
    UnitsService unitsService;


    @Override
    public User save(User user) {
        String encode = bCryptPasswordEncoder.encode("qwer1234");
        user.setPassword(encode);
        return userDao.save(user);
    }

    @Override
    public boolean delete(Integer id) {
        userDao.deleteById(id);
        return true;
    }

    @Override
    public List<User> findAll() {
        return userDao.findAll();
    }

    @Override
    public User update(User user) {
        return userDao.save(user);
    }

    @Override
    public User findByUserName(String userName) {
        return userDao.findByUsername(userName);
    }

    @Override
    public List<UserShenRe> findByUserId(Integer userId) {

        return findByUniteId(userDao.findById(userId).get().getUnitsId());
    }

    @Override
    public List<UserShenRe> findByUniteId(Integer unitsId) {

        return userDao.findAllByUnitsId(unitsId).stream().map(User::toRe).collect(Collectors.toList());
    }

    @Override
    public List<User> findAllByUnite(Integer unitsId) {
        return userDao.findAllByUnitsId(unitsId);
    }


    @Override
    public UserPage findAllByUnitePage(UserConditionsVo userConditionsVo) {
//        Pageable pageable = PageRequest.of(page, size, Sort.Direction.ASC, "seq");
//        Page<User> all = getContacts(unitsId, pageable);
//        return UserPage.builder()
//                .data(all.getContent())
//                .page(page)
//                .size(size)
//                .total((int)all.getTotalElements())
//                .build();
       Integer page=userConditionsVo.getPage();
       Integer size=userConditionsVo.getSize();
       List<MemberThat> memberThats= new ArrayList<>();
               userDao.findAllByUnitsId(userConditionsVo.getUnitsId()).forEach(
                       user -> {
                       MemberThat memberThat=user.toVo();
                       memberThat.setUnitsName(unitsService.findById(user.getUnitsId()).getName());
                       Mgrcert mgrcert= mgrcertDao.findByUserId(user.getUserId());
                       if (mgrcert!=null) {
                           memberThat.setCertName(mgrcert.getCertName());
                           memberThat.setCertNum(mgrcert.getCertNum());
                           memberThat.setIssueDate(mgrcert.getIssueDate());
                           memberThat.setExpiryDate(mgrcert.getExpiryDate());
                           memberThat.setIsExpiry(mgrcert.getIsExpiry());
                           memberThat.setRemaining(mgrcert.getExpiryDate().getTime() - mgrcert.getIssueDate().getTime());
                       }else {
                           memberThat.setRemaining(0L);
                       }
                       memberThats.add(memberThat);

                       }
               );

               if (userConditionsVo.getDim()!=null) {
                   for (int i = 0; i < memberThats.size(); i++) {
                       if (!Objects.requireNonNull(JacksonUtil.toJSon(memberThats.get(i))).contains(userConditionsVo.getDim()))
                           memberThats.remove(i);
                   }
               }

        memberThats.sort((o1, o2) -> {
            //升序
            return o2.getRemaining().compareTo(o1.getRemaining());
        });


        int count=memberThats.size();
        if (size>count){
            return UserPage.builder()
            .total(count)
            .page(page)
            .size(size)
            .data(memberThats).build();
        }
        int countPage=count/size;
        if (count%size!=0){
            countPage=countPage+1;
        }
        if (page>=countPage){
            return UserPage.builder()
                    .total(count)
                    .page(page)
                    .size(size)
                    .data(memberThats.subList((page-1)*size,count)).build();
        } else {
            return UserPage.builder()
                    .total(count)
                    .page(page)
                    .size(size)
                    .data(memberThats.subList((page-1)*size,page*size)).build();
        }

    }


//    private Page<User> getContacts(Integer depId, Pageable pageable) {
//        Specification<User> contactSpecification = new Specification<User>() {
//            @Override
//            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
//                Predicate predicate = criteriaBuilder.equal(root.get("department"), depId);
//                Predicate status = criteriaBuilder.equal(root.get("status"), "1");
//                return criteriaBuilder.and(predicate, status);
//            }
//        };
//        return userDao.findAll(contactSpecification, pageable);
//    }

    @Override
    public Integer updatePw(UserUpdatePw userUpdatePw) {
        Optional<User> userOpt = userDao.findById(userUpdatePw.getUserId());

        if (userOpt.isPresent()){
            User user=userOpt.get();
            if (userOpt.get().getPassword().equals(bCryptPasswordEncoder.encode(userUpdatePw.getPassword()))){
              user.setPassword(bCryptPasswordEncoder.encode(userUpdatePw.getNewPassWord()));
              User user1= userDao.save(user);
               return user1.getUserId();
            }else {
                return -1;
            }
        }else {
                return -2;
        }
    }

    @Override
    public MemberThat findById(Integer userId) {
        MemberThat memberThat=userDao.findById(userId).get().toVo();
        Mgrcert mgrcert= mgrcertDao.findByUserId(userId);
        memberThat.setUnitsName(unitsService.findById(memberThat.getUnitsId()).getName());
        if (mgrcert!=null) {
            memberThat.setCertName(mgrcert.getCertName());
            memberThat.setCertNum(mgrcert.getCertNum());
            memberThat.setIssueDate(mgrcert.getIssueDate());
            memberThat.setExpiryDate(mgrcert.getExpiryDate());
            memberThat.setIsExpiry(mgrcert.getIsExpiry());
            memberThat.setRemaining(mgrcert.getExpiryDate().getTime() - mgrcert.getIssueDate().getTime());
        }else {
            memberThat.setRemaining(0L);
        }


        return memberThat;
    }

    @Override
    public List<User> findSubordinate(Integer userId) {
       Integer unitsId=userDao.findById(userId).get().getUnitsId();
        return userDao.findAllByUnitsIdIn(unitsService.findListSubordinateId(unitsId));

    }

    @Override
    public List<UserTrainVo> findByIdUserTarinVo(Integer userId) {
         List<UserTrainVo> list=new ArrayList<>();
         Integer unitsId=userDao.findById(userId).get().getUnitsId();
         Units units=unitsService.findById(unitsId);
         userDao.findAllByUnitsIdIn(unitsService.findListSubordinateId(unitsId)).forEach(
             user -> {
                UserTrainVo userTrainVo= user.toUserTrainVo();
                if (user.getTrainStatus()==1 || user.getTrainStatus()==2){
                    userTrainVo.setIsMustJoin(0);
                }else {
                    userTrainVo.setIsMustJoin(1);
                }
                userTrainVo.setUnitsName(unitsService.findById(user.getUnitsId()).getName());
                list.add(userTrainVo);
             }
         );
         list.sort(Comparator.comparing(UserTrainVo::getIsMustJoin).reversed());
        return list;
    }

    @Override
    public List<UnitsTrainVo> findByIdUnitsTrainVo(Integer userId) {
        return unitsService.findListUnitsTrainVo(userDao.findById(userId).get().getUnitsId());
    }


    @Override
    public List<UserTrainVo> findByIdListUserTarinVo(List<Integer> userId) {
        List<UserTrainVo> list=new ArrayList<>();
        userDao.findAllByUserIdIn(userId).forEach(
                user -> {
                    UserTrainVo userTrainVo= user.toUserTrainVo();
                    if (user.getTrainStatus()==1 || user.getTrainStatus()==2){
                        userTrainVo.setIsMustJoin(0);
                    }else {
                        userTrainVo.setIsMustJoin(1);
                    }
                    userTrainVo.setUnitsName(unitsService.findById(user.getUnitsId()).getName());
                    list.add(userTrainVo);
                }
        );
        return list;
    }

    @Override
    public HandoverUser findByIdHandoverUser(Integer userId) {
        HandoverUser handoverUser = userDao.findById(userId).get().toHandoverUserVo();
        Mgrcert mgrcert = mgrcertDao.findByUserId(userId);
        if (handoverUser.getTrainStatus()!=2) {
            handoverUser.setCertName(mgrcert.getCertName());
            handoverUser.setCertNum(mgrcert.getCertNum());
            handoverUser.setIssueDate(mgrcert.getIssueDate());
            handoverUser.setExpiryDate(mgrcert.getExpiryDate());
            handoverUser.setIsExpiry(mgrcert.getIsExpiry());
            handoverUser.setUnitsName(unitsService.findById(handoverUser.getUnitsId()).getName());
        }
        return handoverUser;
    }

    @Override
    public List<UserSuperiorVo> findUserSuperiorVo(Integer userId) {

        List<UserSuperiorVo> list=new ArrayList<>();
        User user= userDao.findById(userId).get();

        userDao.findAllByUnitsIdIn(unitsService.findSuperiorByunitsId(user.getUnitsId())).forEach(
                user1 -> {
                    UserSuperiorVo userSuperiorVo=user1.toUserSuperiorVo();
                    userSuperiorVo.setUnitsName(unitsService.findById(user1.getUnitsId()).getName());
                   list.add(userSuperiorVo);
                }
        );
        return list;
    }


}
