package com.fzm.mall.server.admin.auth_center.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fzm.mall.server.admin.auth_center.entity.dto.RoleDTO;
import com.fzm.mall.server.admin.auth_center.entity.dto.RoleEditDTO;
import com.fzm.mall.server.admin.auth_center.entity.vo.AdminRoleDetailVO;
import com.fzm.mall.server.admin.auth_center.entity.vo.AdminRoleListVO;
import com.fzm.mall.server.admin.auth_center.entity.vo.AdminRoleVO;
import com.fzm.mall.server.admin.auth_center.entity.vo.RoleAuthMenuVO;
import com.fzm.mall.server.admin.auth_center.enums.status.AdminRoleStatusEnum;
import com.fzm.mall.server.admin.auth_center.enums.type.AdminRoleTypeEnum;
import com.fzm.mall.server.admin.auth_center.mapper.AdminRoleMapper;
import com.fzm.mall.server.admin.auth_center.model.AdminRole;
import com.fzm.mall.server.admin.auth_center.service.IAdminRoleService;
import com.fzm.mall.server.admin.auth_center.service.IAuthMenuService;
import com.fzm.mall.server.admin.home_page.enums.type.AdminTypeEnum;
import com.fzm.mall.server.admin.util.UUIDUtil;
import org.dozer.DozerBeanMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author wangp
 * @date 2021/4/8 13:41
 * @description 管理员角色 服务实现类
 * @since JDK 1.8
 */
@Service
@Transactional
public class AdminRoleServiceImpl extends ServiceImpl<AdminRoleMapper, AdminRole> implements IAdminRoleService {

    @Autowired
    private DozerBeanMapper beanMapper;
    @Autowired
    private IAuthMenuService authMenuService;

    @Override
    public void initRole(AdminRole adminRole) {
        boolean exist = isDefaultRoleExist(adminRole.getType());
        if (exist)
            return;
        adminRole.setRoleId(UUIDUtil.getUUID());
        save(adminRole);
    }

    @Override
    public void add(RoleDTO roleDTO) {
        AdminRole adminRole = beanMapper.map(roleDTO, AdminRole.class);
        adminRole.setRoleId(UUIDUtil.getUUID());
        adminRole.setStatus(AdminRoleStatusEnum.NORMAL.getStatus());
        save(adminRole);
    }

    @Override
    public void edit(RoleEditDTO roleEditDTO) {
        AdminRole adminRole = beanMapper.map(roleEditDTO, AdminRole.class);
        UpdateWrapper<AdminRole> uw = new UpdateWrapper<>();
        uw.lambda().eq(AdminRole::getRoleId, adminRole.getRoleId());
        update(adminRole, uw);
    }

    @Override
    public AdminRoleDetailVO detail(String roleId) {
        AdminRoleDetailVO detailVO = beanMapper.map(getByRoleIdIsNotDel(roleId), AdminRoleDetailVO.class);
        List<RoleAuthMenuVO> roleAuthMenu = authMenuService.getRoleAuthMenu(detailVO.getType(), roleId);
        detailVO.setAuth(roleAuthMenu);
        return detailVO;
    }

    public AdminRole getByRoleIdIsNotDel(String roleId) {
        QueryWrapper<AdminRole> qw = new QueryWrapper<>();
        qw.lambda().eq(AdminRole::getRoleId, roleId);
        return getOne(qw);
    }

    @Override
    public IPage<AdminRoleVO> page(String roleId, String roleName, Integer pageNum, Integer pageSize) {
        IPage<AdminRoleVO> iPage = baseMapper.page(new Page<AdminRoleVO>(pageNum, pageSize), roleId, roleName);

        List<AdminRoleVO> records = iPage.getRecords();
        List<AdminRoleVO> newRecords = new ArrayList<>();

        for (AdminRoleVO vo : records) {
            List<String> auth = new ArrayList<>();
            List<Integer> indexs = JSONArray.parseArray(vo.getAuthJson(), Integer.class);
            indexs.forEach(v -> auth.add(authMenuService.getByIndex(v).getMenuName()));
            vo.setAuth(auth);
            vo.setAuthJson("");
            newRecords.add(vo);
        }

        iPage.setRecords(newRecords);
        return iPage;
    }

    @Override
    public void delete(String roleId) {
        LambdaUpdateWrapper<AdminRole> uw = new LambdaUpdateWrapper<>();
        uw.set(AdminRole::getStatus, AdminRoleStatusEnum.DELETE.getStatus());
        uw.eq(AdminRole::getRoleId, roleId);
        update(uw);
    }

    @Override
    public void able(String roleId) {
        LambdaUpdateWrapper<AdminRole> uw = new LambdaUpdateWrapper<>();
        uw.set(AdminRole::getStatus, AdminRoleStatusEnum.NORMAL.getStatus());
        uw.eq(AdminRole::getRoleId, roleId);
        update(uw);
    }

    @Override
    public void disable(String roleId) {
        LambdaUpdateWrapper<AdminRole> uw = new LambdaUpdateWrapper<>();
        uw.set(AdminRole::getStatus, AdminRoleStatusEnum.DISABLE.getStatus());
        uw.eq(AdminRole::getRoleId, roleId);
        update(uw);
    }

    @Override
    public List<AdminRoleListVO> getRoleList(Integer type) {
        Integer arr = null;
        switch (AdminTypeEnum.getByType(type)) {
            case MERCHANT:
                arr = AdminRoleTypeEnum.MERCHANT.getType();
                break;
            case PLATFORM_MERCHANT:
                arr = AdminRoleTypeEnum.PLATFORM_MERCHANT.getType();
                break;
            case PLATFORM_ADMINISTRATOR:
                arr = AdminRoleTypeEnum.PLATFORM.getType();
                break;
        }

        Integer status = AdminRoleStatusEnum.NORMAL.getStatus();
        QueryWrapper<AdminRole> qw = new QueryWrapper<>();
        qw.lambda().eq(AdminRole::getType, arr)
                .eq(AdminRole::getStatus, status);
        return list(qw).stream().map(v -> beanMapper.map(v, AdminRoleListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public boolean isDefaultRoleExist(Integer type) {
        QueryWrapper<AdminRole> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AdminRole::getType, type)
                .ne(AdminRole::getStatus, AdminRoleStatusEnum.DELETE.getStatus());
        return getOne(qw) != null;
    }

    @Override
    public AdminRole getByType(Integer type) {
        QueryWrapper<AdminRole> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AdminRole::getType, type)
                .ne(AdminRole::getStatus, AdminRoleStatusEnum.DELETE.getStatus());
        return getOne(qw);
    }

    @Override
    public AdminRole getByRoleId(String roleId) {
        QueryWrapper<AdminRole> qw = new QueryWrapper<>();
        qw.lambda()
                .eq(AdminRole::getRoleId, roleId)
                .eq(AdminRole::getStatus, AdminRoleStatusEnum.NORMAL.getStatus());
        return getOne(qw);
    }
}


