package com.zjty.tynotes.pas.service.impl;

import com.zjty.tynotes.pas.dao.AuthorityDao;
import com.zjty.tynotes.pas.dao.RoleAuthorityDao;
import com.zjty.tynotes.pas.dao.RoleDao;
import com.zjty.tynotes.pas.dao.UserRoleDao;
import com.zjty.tynotes.pas.entity.Authority;
import com.zjty.tynotes.pas.entity.Role;
import com.zjty.tynotes.pas.entity.RoleAuthority;
import com.zjty.tynotes.pas.service.IRoleService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

/**
 * @Author: mcj
 * @Date: 19-4-29 下午4:08
 * @Version 1.0
 */
@Service
@Transactional(rollbackFor = Exception.class)
public class RoleServiceImpl implements IRoleService {
    private static final Logger logger = LoggerFactory.getLogger(RoleServiceImpl.class);
    @Autowired
    private RoleDao roleDao;
    @Autowired
    private RoleAuthorityDao roleAuthorityDao;
    @Autowired
    private UserRoleDao userRoleDao;
    @Autowired
    private AuthorityDao authorityDao;

    @Override
    public Role findRoleById(String id) {
        Role role = null;
        Optional<Role> byId = roleDao.findById(id);
        List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(id);
        List<String> authorityIds = new ArrayList<>();
        for (RoleAuthority roleAuthority : roleAuthorities) {
            authorityIds.add(roleAuthority.getAuthorityId());
        }
        List<Authority> authorities = authorityDao.findAllByIdIn(authorityIds);
        if(byId.isPresent()){
            role = byId.get();
            role.setAuthorities(authorities);
        }
        return byId.get();
    }

    @Override
    public List<Role> findAll() {
        List<Role> roles = roleDao.findAll();
        for (Role role : roles) {
            List<String> authorityIds = new ArrayList<>();
            List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(role.getId());
            for (RoleAuthority roleAuthority : roleAuthorities) {
                authorityIds.add(roleAuthority.getAuthorityId());
            }
            List<Authority> authorities = authorityDao.findAllByIdIn(authorityIds);
            role.setAuthorities(authorities);
        }
        return roles;
    }

    @Override
    public Role addRole(Role role) {
        roleDao.save(role);
        List<Authority> authorities = role.getAuthorities();
        List<RoleAuthority> roleAuthorities = new ArrayList<>();
        if(authorities!=null){
            for (Authority authority : authorities) {
                RoleAuthority roleAuthority = new RoleAuthority();
                roleAuthority.setRoleId(role.getId());
                roleAuthority.setAuthorityId(authority.getId());
                roleAuthorities.add(roleAuthority);
            }
            roleAuthorityDao.saveAll(roleAuthorities);
        }

        return roleDao.save(role);
    }


    @Override
    public void deleteAll() {
        roleDao.deleteAll();
    }

    @Override
    public boolean deleteRole(String id) {
        try {
            userRoleDao.deleteAllByRoleId(id);
            roleAuthorityDao.deleteAllByRoleId(id);
            roleDao.deleteById(id);
            return true;
        } catch (Exception e) {
            logger.error("mongodb删除角色时出错");
        }
        return false;
    }

    @Override
    public List<Role> findRoleByDepartId(String id) {
        List<Role> roles = roleDao.findAllByDepartmentId(id);
        for (Role role : roles) {
            List<String> authorityIds = new ArrayList<>();
            List<RoleAuthority> roleAuthorities = roleAuthorityDao.findAllByRoleId(role.getId());
            for (RoleAuthority roleAuthority : roleAuthorities) {
                authorityIds.add(roleAuthority.getAuthorityId());
            }
            List<Authority> authorities = authorityDao.findAllByIdIn(authorityIds);
            role.setAuthorities(authorities);
        }
        return roles;
    }

    @Override
    @Transactional
    public Boolean updateRole(Role role) {
        List<Authority> authorities = role.getAuthorities();
        Optional<Role> byId = roleDao.findById(role.getId());
        if(byId.isPresent()){
            Role role1 = byId.get();
            role1.setName(role.getName());
            role1.setDescription(role.getDescription());
            roleDao.save(role1);
            roleAuthorityDao.deleteAllByRoleId(role1.getId());
            List<RoleAuthority> roleAuthorities = new ArrayList<>();
            for (Authority authority : role.getAuthorities()) {
                RoleAuthority roleAuthority = new RoleAuthority();
                roleAuthority.setRoleId(role1.getId());
                roleAuthority.setAuthorityId(authority.getId());
                roleAuthorities.add(roleAuthority);
            }
            roleAuthorityDao.saveAll(roleAuthorities);
            return true;
        }
        return false;
    }
}
