package com.sptg.permissions.biz.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.sptg.common.core.constant.OperationConstant;
import com.sptg.common.core.util.CommonUtil;
import com.sptg.permissions.api.dto.AccountDto;
import com.sptg.permissions.api.dto.AccountRoleDto;
import com.sptg.permissions.api.entity.Account;
import com.sptg.permissions.api.entity.AccountRole;
import com.sptg.permissions.biz.mapper.AccountRoleMapper;
import com.sptg.permissions.biz.service.AccountRoleServiceInterface;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * title: AccountRoleServiceImpl
 * package: com.sptg.permissions.biz.security.impl
 * description: 账号角色-服务层接口实现类
 *
 *                  
 *                 
 */
@Service
@RequiredArgsConstructor
public class AccountRoleServiceImpl extends ServiceImpl<AccountRoleMapper, AccountRole> implements AccountRoleServiceInterface {


    @Override
    public List<Long> selectRoleIdListByAccountId(Serializable accountId) {
        //  获取用户的关联列表
        List<AccountRole> accountRoleList = this.selectListByAccountId(accountId);
        //  获取角色Id列表
        List<Long> roleIdList = new ArrayList<>(accountRoleList.size());
        accountRoleList.forEach(accountRole -> roleIdList.add(accountRole.getRoleId()));
        return roleIdList;
    }

    /**
     * 功能描述: 根据账号Id获取关联列表
     * @param accountId 账号Id
     * @return List<AccountRole>
     *                  
     *                       
     */
    private List<AccountRole> selectListByAccountId(Serializable accountId){
        Wrapper<AccountRole> wrapper = new EntityWrapper<>();
        wrapper.eq("l_account_id",accountId);
        return this.selectList(wrapper);
    }

    @Override
    public Boolean checkRoleIsWasUse(Long roleId) {
        //  获取用户的关联列表
        Wrapper<AccountRole> wrapper = new EntityWrapper<>();
        wrapper.eq("l_role_id",roleId);
        return this.selectCount(wrapper) > OperationConstant.ZERO;
    }

    @Override
    public Page<AccountRole> pagingQuery(AccountRoleDto dto,Page<AccountRole> page) {
        //  获取用户的关联列表
        Wrapper<AccountRole> wrapper = new EntityWrapper<>();
        wrapper.eq("l_role_id",dto.getRoleId());
        //  分页查询关联信息
        return this.selectPage(page, wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean bindUser(AccountRoleDto dto) {
        //  创建时间
        dto.setCreateDate(new Date());
        //  设置创建人Id
        dto.setCreateAccountId(dto.getOnLineUser().getId());
        return this.insert(dto);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public Boolean untieUser(AccountRoleDto dto) {
        Wrapper<AccountRole> wrapper = new EntityWrapper<>();
        wrapper.eq("l_role_id",dto.getRoleId());
        wrapper.in("l_account_id",dto.getAccountIdList());
        return this.delete(wrapper);
    }

    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void batchInsertByAccount(AccountDto dto) {
        List<Long> roleIdList = CommonUtil.stringToLongList(dto.getRoleIds());
        if (roleIdList.size() > 0) {
            List<AccountRole> accountRoleList = new ArrayList<>(roleIdList.size());
            roleIdList.forEach(roleId -> {
                AccountRole entity = new AccountRole();
                //  账号Id
                entity.setAccountId(dto.getId());
                //  角色Id
                entity.setRoleId(roleId);
                //  创建时间
                entity.setCreateDate(dto.getCreateDate());
                //  创建人Id
                entity.setCreateAccountId(dto.getCreateAccountId());
                accountRoleList.add(entity);
            });
            this.insertBatch(accountRoleList);
        }
    }



    @Override
    @Transactional(rollbackFor = Throwable.class)
    public void batchInsertOrUpdateByAccount(AccountDto dto) {
        List<Long> roleIdList = CommonUtil.stringToLongList(dto.getRoleIds());
        if (roleIdList.size() == 0){
            this.clearAccountRole(dto.getId());
            return;
        }
        //  获取当前用户
        Account onLineUser = dto.getOnLineUser();
        Date nowTime = new Date();
        //  获取账号的关联列表
        List<AccountRole> list = this.selectListByAccountId(dto.getId());
        //  需要新增的关联列表
        List<AccountRole> newList = new ArrayList<>();
        skip:
        for (int i = 0; i < roleIdList.size(); i++){
            long roleId = roleIdList.get(i);
            for (int j = 0; j < list.size(); j ++ ){
                AccountRole entity = list.get(j);
                //  过滤已经拥有的角色
                if (entity.getRoleId().equals(roleId)){
                    roleIdList.remove(i);
                    list.remove(j);
                    --i;
                    continue skip;
                }
                //  过滤最顶级的角色
                if (entity.getRoleId() == OperationConstant.ONE){
                    list.remove(j);
                    --j;
                }
            }
            AccountRole entity = new AccountRole();
            //  账号Id
            entity.setAccountId(dto.getId());
            //  角色Id
            entity.setRoleId(roleId);
            //  创建时间
            entity.setCreateDate(nowTime);
            //  创建人Id
            entity.setCreateAccountId(onLineUser.getCreateAccountId());
            newList.add(entity);
        }
        //  删除多余的关联
        if (list.size() > OperationConstant.ZERO){
            List<Long> deleteList = new ArrayList<>(list.size());
            list.forEach(entity -> deleteList.add(entity.getId()));
            this.deleteBatchIds(deleteList);
        }
        //  新增关联
        if (newList.size() > OperationConstant.ZERO) {
            this.insertBatch(newList);
        }
    }

    @Override
    public void clearAccountRole(Long accountId) {
        //  删除该账号下所有的角色关联
        Wrapper<AccountRole> wrapper = new EntityWrapper<>();
        wrapper.eq("l_account_id",accountId);
        //  过滤最顶级的角色
        wrapper.notIn("l_role_id",OperationConstant.ONE);
        this.delete(wrapper);
    }
}
