package com.gree.mall.manager.logic.admin;

import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.gree.mall.manager.bean.admin.AdminUserCom;
import com.gree.mall.manager.exception.RemoteServiceException;
import com.gree.mall.manager.logic.common.CommonLogic;
import com.gree.mall.manager.plus.entity.AdminCompany;
import com.gree.mall.manager.plus.entity.AdminRole;
import com.gree.mall.manager.plus.entity.AdminUser;
import com.gree.mall.manager.plus.entity.AdminUserModuleRela;
import com.gree.mall.manager.plus.service.AdminCompanyService;
import com.gree.mall.manager.plus.service.AdminRoleService;
import com.gree.mall.manager.plus.service.AdminUserModuleRelaService;
import com.gree.mall.manager.plus.service.AdminUserService;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Objects;

@Service
@RequiredArgsConstructor
public class AdminRoleLogic {

    private final AdminRoleService adminRoleService;
    private final AdminUserService adminUserService;
    private final CommonLogic commonLogic;
    private final AdminUserModuleRelaService adminUserModuleRelaService;
    private final AdminCompanyService adminCompanyService;

    /**
     * 角色列表
     */
    public IPage<AdminRole> listPage(HttpServletRequest request, String companyWechatName, String adminCompanyId, Integer type, Integer pageNo, Integer pageSize) {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);
        List<String> companyIds = adminUser.getAdminCompanyIds();

        Integer userType = this.checkUserType(adminUser);

        return adminRoleService.lambdaQuery()
                .eq(StringUtils.isNotBlank(companyWechatName), AdminRole::getCompanyName, companyWechatName)
                .eq(StringUtils.isNotBlank(adminCompanyId), AdminRole::getCompanyId, adminCompanyId)
                .eq(Objects.nonNull(type), AdminRole::getType, type)
                .and(v -> {
                    if (!adminUser.getUserName().equals("admin") && adminUser.getType().equals(0)) {
                        v.in(CollectionUtils.isNotEmpty(companyIds), AdminRole::getCompanyId, companyIds)
                                .or()
                                .isNull(AdminRole::getCompanyId);
                    } else {
                        v.in(CollectionUtils.isNotEmpty(companyIds), AdminRole::getCompanyId, companyIds);
                    }
                })
                .ge(userType > 0, AdminRole::getType, userType)
                .orderByAsc(AdminRole::getType)
                .page(new Page<>(pageNo, pageSize));
    }

    private Integer checkUserType(AdminUserCom adminUser) {
        int userType = 0;
        if (adminUser.getType() == 1 || adminUser.getType() == 3) {
            userType = 1;
        } else if (adminUser.getType() == 2 || adminUser.getType() == 4) {
            userType = 2;
        }
        return userType;
    }

    /**
     * 新增角色
     */
    public void add(HttpServletRequest request, AdminRole adminRole) {
        AdminUserCom adminUser = commonLogic.getAdminUser(request);

        if (Objects.isNull(adminRole.getType())) {
            throw new RemoteServiceException("适用机构不能为空");
        }

        if (adminUser.getType() != 0 && adminRole.getType() == 0) {
            throw new RemoteServiceException("适用机构参数异常");
        }

        if (StringUtils.isBlank(adminRole.getName())) {
            throw new RemoteServiceException("角色名称不能为空");
        }

        if (StringUtils.isBlank(adminRole.getCompanyId()) && adminUser.getType() > 0) {
            adminRole.setCompanyId(adminUser.getCompanyId())
                    .setCompanyName(adminUser.getCompanyName());
        }

        if (adminRoleService.lambdaQuery()
                .eq(AdminRole::getCompanyId, adminRole.getCompanyId())
                .eq(AdminRole::getName, StringUtils.trim(adminRole.getName()))
                .count() > 0) {
            throw new RemoteServiceException("同商户的角色名称已重复");
        }

        if (StringUtils.isNotBlank(adminRole.getParentRoleId())) {
            final AdminRole parentRole = adminRoleService.getById(adminRole.getParentRoleId());
            adminRole.setParentRoleName(parentRole.getName());
        }

        if (StringUtils.isNotBlank(adminRole.getCompanyId())) {
            final AdminCompany company = adminCompanyService.getById(adminRole.getCompanyId());
            adminRole.setCompanyName(company.getAdminCompanyName());
        }

        adminRoleService.save(adminRole);
    }

    /**
     * 修改角色
     */
    @Transactional
    public void update(AdminRole adminRole) {
        AdminUserCom adminUser = commonLogic.getAdminUser();

        if (StringUtils.isBlank(adminRole.getName())) {
            throw new RemoteServiceException("角色名称不能为空");
        }

        if (adminRoleService.lambdaQuery()
                .eq(AdminRole::getCompanyId, adminRole.getCompanyId())
                .eq(AdminRole::getName, StringUtils.trim(adminRole.getName()))
                .ne(AdminRole::getAdminRoleId, adminRole.getAdminRoleId())
                .count() > 0) {
            throw new RemoteServiceException("同商户的角色名称已重复");
        }

        final AdminRole oldData = adminRoleService.getById(adminRole.getAdminRoleId());
        // 父级角色id不为空查询父级角色名填充
        if (StringUtils.isNotBlank(adminRole.getParentRoleId())) {
            final AdminRole parentRole = adminRoleService.getById(adminRole.getParentRoleId());
            adminRole.setParentRoleName(parentRole.getName());
        }

        if (adminRole.getName() != null) {
            // 更新账号使用对应的角色名
            adminUserService.lambdaUpdate()
                    .set(AdminUser::getRoleName, adminRole.getName())
                    .eq(AdminUser::getRoleId, adminRole.getAdminRoleId())
                    .update();

            // 更新所有子级的父级角色名
            adminRoleService.lambdaUpdate()
                    .set(AdminRole::getParentRoleName, adminRole.getName())
                    .eq(AdminRole::getParentRoleId, adminRole.getAdminRoleId())
                    .update();
        }

        adminRoleService.updateById(adminRole);

        // 本次编辑与历史父级不一致
        if (!adminRole.getParentRoleId().equals(oldData.getParentRoleId())) {
            // 清空角色已选权限
            adminUserModuleRelaService.lambdaUpdate()
                    .eq(AdminUserModuleRela::getAdminRoleId, oldData.getAdminRoleId())
                    .remove();
        }
    }

    /**
     * 删除角色
     */
    public void delete(String adminRoleId) throws RemoteServiceException {
        final Integer isOpen = adminRoleService.lambdaQuery()
                .eq(AdminRole::getAdminRoleId, adminRoleId)
                .eq(AdminRole::getIsOpen, false)
                .count();
        if (isOpen > 0) {
            throw new RemoteServiceException("该角色不允许删除");
        }
        //不允许删除使用该角色的帐号
        Integer count = adminUserService.lambdaQuery().eq(AdminUser::getRoleId, adminRoleId).count();
        if (count > 0) {
            throw new RemoteServiceException("共有" + count + "个帐号使用该角色,不可删除");
        }
        adminRoleService.removeById(adminRoleId);
    }

    /**
     * 详情
     */
    public AdminRole detail(String adminRoleId) {
        return adminRoleService.getById(adminRoleId);
    }


}
