package com.zjty.tynotes.weekly.subject.service.impl;

import com.zjty.tynotes.job.basic.entity.database.Work;
import com.zjty.tynotes.job.basic.repository.WorkRepository;
import com.zjty.tynotes.job.status.entity.Personnel;
import com.zjty.tynotes.job.status.entity.vo.UserWorkData;
import com.zjty.tynotes.job.status.service.InternalService;
import com.zjty.tynotes.pas.dao.*;
import com.zjty.tynotes.pas.entity.*;
import com.zjty.tynotes.pas.entity.vo.PageRequest;
import com.zjty.tynotes.pas.entity.vo.PageResponse;
import com.zjty.tynotes.weekly.subject.dao.ProblemDao;
import com.zjty.tynotes.weekly.subject.entity.vo.Problem;
import com.zjty.tynotes.weekly.subject.entity.vo.UserVo;
import com.zjty.tynotes.weekly.subject.service.UserManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

import java.lang.reflect.Array;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @Author gwj
 * @create 2020/3/2 13:07
 */
@Service
public class UserManageServiceImpl implements UserManageService {
    @Autowired
    private BCryptPasswordEncoder bCryptPasswordEncoder;
    @Autowired
    private PasUserDao pasUserDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleAuthorityDao roleAuthorityDao;
    @Autowired
    private AuthorityDao authorityDao;
    @Autowired
    private DepartmentDao departmentDao;
    @Autowired
    private InternalService internalService;


    private Map<String, UserWorkData> userWorkDataMap = new ConcurrentHashMap<>();

    @Autowired
    private ProblemDao problemDao;

    @Override
    public User findUserById(String id) {
        Optional<User> optional = pasUserDao.findById(id);
        User user = null;
        if(optional.isPresent()){
            user = optional.get();
            List<String> roleIds = new ArrayList<>();
            List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
            if(userRoles!=null){
                for (UserRole userRole : userRoles) {
                    roleIds.add(userRole.getRoleId());
                }
            }
            List<Role> roles = roleDao.findAllByIdIn(roleIds);
            if(roles!=null){
                for (Role role : roles) {
                    List<String> authoritityIds = new ArrayList<>();
                    List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(role.getId());
                    for (RoleAuthority roleAuthority : roleAuthorities) {
                        authoritityIds.add(roleAuthority.getAuthorityId());
                    }
                    List<Authority> authorities = authorityDao.findAllByIdIn(authoritityIds);
                    role.setAuthorities(authorities);
                }
            }
            user.setRoles(roles);
        }
        return user;
    }

    public static void main(String[] args) {
        DecimalFormat df = new DecimalFormat("#.00");
        double a = 0.3333333333333333333333333333333d;
        BigDecimal bg = new BigDecimal(a);
        double v = bg.setScale(2, BigDecimal.ROUND_HALF_UP).doubleValue();
        String format = df.format(a);
        Number parse = null;
        try {
            parse = df.parse(format);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        System.out.println(parse.doubleValue());
        System.out.println(v);
    }

    /**
     * 查询人员列表
     * @param pageRequest
     * @return
     */
    @Override
    public PageResponse<UserVo> findUserList (PageRequest pageRequest) throws ParseException {
        DecimalFormat df = new DecimalFormat("#.00");
        List<UserVo> userVos = new ArrayList<>();
        PageResponse<UserVo> pageResponse = new PageResponse();
        String deId = pageRequest.getDeId();
        List<User> users = null;
        if(pageRequest.getStatus()!=null){
            String status = pageRequest.getStatus();
            users = pasUserDao.findAllByStatus(status);
        }else{
            users = pasUserDao.findAll();
        }
        List<User> userList = new ArrayList<>();
        if(users!=null){
            for (User user : users) {
                List<String> departmentIds = user.getDepartmentIds();
                if(departmentIds!=null){
                    for (String departmentId : departmentIds) {
                        if(departmentId.equals(deId)){
                            userList.add(user);
                        }
                    }
                }
            }
        }

        int currentPage = pageRequest.getCurrentPage();
        int pageSize = pageRequest.getPageSize();
        int start = (currentPage-1)*pageSize;
        int end = start+pageSize;
        int totalPage = 0;
        if((userList.size()/pageSize)==0){
            totalPage = (userList.size())/pageSize;
        }else{
            totalPage = (userList.size())/pageSize + 1;
        }

        if(pageRequest.getSort()!=null && pageRequest.getSort()==1) {
            Collections.sort(userList, new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    return o1.getWorkNum()-o2.getWorkNum();
                }
            });
        }else{
            Collections.sort(userList, new Comparator<User>() {
                @Override
                public int compare(User o1, User o2) {
                    return o2.getWorkNum()-o1.getWorkNum();
                }
            });
        }

        List<User> users1 = null;
        if(totalPage>currentPage){
            users1 = userList.subList(start, end);
            for (User user : users1) {
                List<String> roleIds = new ArrayList<>();
                List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
                for (UserRole userRole : userRoles) {
                    roleIds.add(userRole.getRoleId());
                }
                List<Role> roles = roleDao.findAllByIdIn(roleIds);
                user.setRoles(roles);
                UserVo userVo = new UserVo(user);
                if(pageRequest.getStartTime()==null&&pageRequest.getEndTime()==null){

                    UserWorkData userWorkData = userWorkDataMap.get(user.getId());
                    if(userWorkData!=null){
                        userVo.setAverageScore(df.parse(df.format(userWorkData.getAverageScore())).doubleValue());
                        userVo.setCompletedCount(userWorkData.getCompletedNum());
                        userVo.setWorkingCount(userWorkData.getUnCompletedNum());
                        userVo.setAverageWorkNum(df.parse(df.format(userWorkData.getAverageWorkNum())).doubleValue());
                    }
                }else{
                    UserWorkData userWorkData = internalService.personnelWorkMsg(user.getId(), pageRequest.getStartTime(), pageRequest.getEndTime());
                    if(userWorkData!=null){
                        userVo.setAverageScore(df.parse(df.format(userWorkData.getAverageScore())).doubleValue());
                        userVo.setCompletedCount(userWorkData.getCompletedNum());
                        userVo.setWorkingCount(userWorkData.getUnCompletedNum());
                        userVo.setAverageWorkNum(df.parse(df.format(userWorkData.getAverageWorkNum())).doubleValue());
                    }
                }
                userVos.add(userVo);
            }
            pageResponse.setRows(userVos);
            pageResponse.setTotalCount(userList.size());
            return pageResponse;
        }else{
            users1 = userList.subList(start, userList.size());
            for (User user : users1) {
                List<String> roleIds = new ArrayList<>();
                List<UserRole> userRoles = userRoleDao.findAllByUserId(user.getId());
                for (UserRole userRole : userRoles) {
                    roleIds.add(userRole.getRoleId());
                }
                List<Role> roles = roleDao.findAllByIdIn(roleIds);
                user.setRoles(roles);
                UserVo userVo = new UserVo(user);
                if(pageRequest.getStartTime()==null&&pageRequest.getEndTime()==null){
                    UserWorkData userWorkData = userWorkDataMap.get(user.getId());
                    if(userWorkData!=null){
                        userVo.setAverageScore(userWorkData.getAverageScore());
                        userVo.setCompletedCount(userWorkData.getCompletedNum());
                        userVo.setWorkingCount(userWorkData.getUnCompletedNum());
                        userVo.setAverageWorkNum(userWorkData.getAverageWorkNum());
                    }
                }else{
                    UserWorkData userWorkData = internalService.personnelWorkMsg(user.getId(), pageRequest.getStartTime(), pageRequest.getEndTime());
                    if(userWorkData!=null){
                        userVo.setAverageScore(userWorkData.getAverageScore());
                        userVo.setCompletedCount(userWorkData.getCompletedNum());
                        userVo.setWorkingCount(userWorkData.getUnCompletedNum());
                        userVo.setAverageWorkNum(userWorkData.getAverageWorkNum());
                    }
                }
                userVos.add(userVo);
            }
            pageResponse.setRows(userVos);
            pageResponse.setTotalCount(userList.size());
            return pageResponse;
        }

    }


    /**
     * 查询可查看的部门列表
     * @param id
     * @return
     */
    @Override
    public List<Department> findDepartmentList(String id) {
        List<UserRole> userRoles = userRoleDao.findAllByUserId(id);
        List<String> roleIds = new ArrayList<>();
        List<String> departmentIds = new ArrayList<>();
        for (UserRole userRole : userRoles) {
            roleIds.add(userRole.getRoleId());
        }
        List<Role> roles = roleDao.findAllByIdIn(roleIds);
        for (Role role : roles) {
            List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(role.getId());
            List<String> authorityIds = new ArrayList<>();
            for (RoleAuthority roleAuthority : roleAuthorities) {
                authorityIds.add(roleAuthority.getAuthorityId());
            }
            Authority authority = authorityDao.findByIdInAndName(authorityIds, "查看人员");
            if(authority!=null){
                String departmentId = role.getDepartmentId();
                departmentIds.add(departmentId);
            }
        }
        List<Department> departmentList = departmentDao.findAllByIdIn(departmentIds);
        getDepartments(departmentList);
//        getDepartments(departmentIdList,departmentIds);
//        List<Department> departments = departmentDao.findAllByIdIn(departmentIdList);

        return departmentList;
    }

    /**
     * 递归获取该部门下的所有部门列表
     * @param departmentIdList
     * @param departmentIds
     */
    public void getDepartments(List<String> departmentIdList,List<String> departmentIds) {
        for (String string : departmentIds) {
            if(departmentIdList.contains(string)){
                continue;
            }

            List<Department> departmentList = departmentDao.findAllByParentId(string);
            List<String> departments = new ArrayList<>();
            for (Department department : departmentList) {
                departments.add(department.getId());
            }
            departmentIdList.add(string);
            getDepartments(departmentIdList,departments);
        }
    }

    @Override
    public boolean updatePas(User user) {
        String encode = bCryptPasswordEncoder.encode(user.getPassword());
        user.setPassword(encode);
        pasUserDao.save(user);
        return true;
    }

    @Override
    public User findfindUserByUsername(String username) {
        return pasUserDao.findByUsername(username);
    }

    @Override
    public User updateSelf(User user,User userById) {
        userById.setPhone1(user.getPhone1());
        userById.setPhone2(user.getPhone2());
        userById.setEmail(user.getEmail());
        userById.setAddress(user.getAddress());
        pasUserDao.save(userById);
        return userById;
    }

    /**
     * 上传bug
     * @param problem
     * @return
     */
    @Override
    public Problem submitProblem(Problem problem) {
        Optional<User> optional = pasUserDao.findById(problem.getUserId());
        if(optional.isPresent()){
            User user = optional.get();
            problem.setName(user.getUsername());
            problem.setSubmitTime(new Date());
        }
        return problemDao.save(problem);
    }

    /**
     * 查找bug
     * @return
     */
    @Override
    public List<Problem> searchProblem() {
        return problemDao.findAll();
    }

    /**
     * 修改bug
     * @param problem
     * @return
     */
    @Override
    public Problem putProblem(Problem problem) {
        return problemDao.save(problem);
    }

    /**
     * 暂时没有用到
     * @param des
     * @param deps
     * @return
     */
    private List<Department> findDepartmentList(List<Department> des, List<Department> deps){
        for (Department department : deps) {
            if(!des.contains(department)){
                des.add(department);
            }
        }
        for (Department department : deps) {
            List<Department> departments = departmentDao.findAllByParentId(department.getId());
            if(departments!=null){
                findDepartmentList(des,departments);
            }
        }
        return des;
    }

    /**
     * 递归获得部门树
     * @param departments
     */
    public void getDepartments(List<Department> departments) {
        for (Department department : departments) {
            List<Department> departmentList = departmentDao.findAllByParentId(department.getId());
            getDepartments(departmentList);
            department.setDepartments(departmentList);
        }
    }


    @Scheduled(cron = "0/30 * * * * ? ")
    public void userWorkDataMap(){
        List<User> users = pasUserDao.findAll();
        if(users!=null){
            users.forEach(user -> {
                UserWorkData userWorkData = internalService.personnelWorkMsgAll(user.getId());
                if(userWorkData!=null){
                    userWorkDataMap.put(user.getId(),userWorkData);
                }
            });
        }

    }




}
