package cn.iocoder.yudao.module.system.service.service;

import cn.iocoder.yudao.framework.common.config.CommonStr;
import cn.iocoder.yudao.framework.common.enums.CommonStatusEnum;
import cn.iocoder.yudao.framework.datapermission.core.rule.DataPermissionRule;
import cn.iocoder.yudao.framework.tenant.core.util.TenantUtils;
import cn.iocoder.yudao.module.system.controller.admin.permission.vo.role.RoleSaveReqVO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantPackageDO;
import cn.iocoder.yudao.module.system.enums.permission.RoleCodeEnum;
import cn.iocoder.yudao.module.system.enums.permission.RoleTypeEnum;
import cn.iocoder.yudao.module.system.service.permission.PermissionService;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.tenant.TenantService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import cn.iocoder.yudao.module.system.controller.admin.service.vo.*;
import cn.iocoder.yudao.module.system.dal.dataobject.service.ServicePackageDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.system.dal.mysql.service.ServicePackageMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.*;

/**
 * 服务套餐 Service 实现类
 *
 * @author 后台管理员
 */
@Service
@Validated
public class ServicePackageServiceImpl implements ServicePackageService {

    @Resource
    private ServicePackageMapper servicePackageMapper;
    @Resource
    private RoleService roleService;
    @Resource
    private TenantService tenantService;
    @Resource
    private PermissionService permissionService;

    @Override
    public String createServicePackage(ServicePackageSaveReqVO createReqVO) {
        // 插入
        ServicePackageDO servicePackage = BeanUtils.toBean(createReqVO, ServicePackageDO.class);
        servicePackageMapper.insert(servicePackage);
        //自动在点亮科技租户创建对应的角色并赋予权限
        TenantUtils.execute(CommonStr.TENANT_ID, () -> {
            //依据角色编码删除原有角色
            roleService.deleteRole(createReqVO.getId());
            // 创建新角色并赋予权限
            createRole(createReqVO);
        });
        // 返回
        return servicePackage.getId();
    }

    /**
     * 自动为新建的服务套餐创建角色并赋予权限
     * @author vinjor-M
     * @date 14:08 2024/8/2
     * @param createReqVO 服务套餐对象
    **/
    private Long createRole(ServicePackageSaveReqVO createReqVO) {
        // 创建角色
        RoleSaveReqVO reqVO = new RoleSaveReqVO();
        reqVO.setName(createReqVO.getName()+"业务管理员").setCode(createReqVO.getId())
                .setSort(0).setRemark("系统自动生成");
        Long roleId = roleService.createRole(reqVO, RoleTypeEnum.SYSTEM.getType());
        // 分配权限
        permissionService.assignRoleMenu(roleId, createReqVO.getMenuIds());
        return roleId;
    }

    @Override
    public void updateServicePackage(ServicePackageSaveReqVO updateReqVO) {
        // 校验存在
        if (servicePackageMapper.selectById(updateReqVO.getId()) == null) {
            //不存在，执行插入
            this.createServicePackage(updateReqVO);
        }else {
            // 更新
            ServicePackageDO updateObj = BeanUtils.toBean(updateReqVO, ServicePackageDO.class);
            servicePackageMapper.updateById(updateObj);
        }
    }

    @Override
    public void deleteServicePackage(String id) {
        // 校验存在
        validateServicePackageExists(id);
        // 校验正在使用本服务的租户
        validServicePackageUsed(id);
        // 删除
        servicePackageMapper.deleteById(id);
    }

    private void validateServicePackageExists(String id) {
        if (servicePackageMapper.selectById(id) == null) {
            throw exception(SERVICE_PACKAGE_NOT_EXISTS);
        }
    }

    private void validServicePackageUsed(String id) {
        if (tenantService.getTenantCountByPackageId(id) > 0) {
            throw exception(TENANT_PACKAGE_USED);
        }
    }

    @Override
    public ServicePackageDO validServicePackage(String id) {
        ServicePackageDO servicePackage = servicePackageMapper.selectById(id);
        if (servicePackage == null) {
            throw exception(SERVICE_PACKAGE_NOT_EXISTS);
        }
        if (servicePackage.getStatus().equals(CommonStatusEnum.DISABLE.getStatus())) {
            throw exception(SERVICE_PACKAGE_DISABLE, servicePackage.getName());
        }
        return servicePackage;
    }

    @Override
    public ServicePackageDO getServicePackage(String id) {
        return servicePackageMapper.selectById(id);
    }

    @Override
    public PageResult<ServicePackageDO> getServicePackagePage(ServicePackagePageReqVO pageReqVO) {
        return servicePackageMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ServicePackageDO> getServicePackageListByStatus(Integer status) {
        return servicePackageMapper.selectListByStatus(status);
    }

}