package com.cf.imes.module.report.service.dataset;

import cn.hutool.core.util.ObjectUtil;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.security.core.util.SecurityFrameworkUtils;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetReqVO;
import com.cf.imes.module.report.controller.admin.dataset.vo.ReportDatasetSaveReqVO;
import com.cf.imes.module.report.dal.dataobject.dataset.ReportDatasetDO;
import com.cf.imes.module.report.dal.dataobject.datasource.ReportDatasourceDO;
import com.cf.imes.module.report.dal.mysql.dataset.ReportDatasetMapper;
import com.cf.imes.module.report.dal.mysql.datasource.ReportDatasourceMapper;
import com.cf.imes.module.report.enums.template.ReportTemplateTypeEnum;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import jakarta.annotation.Resource;
import java.util.List;

import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASET_NOT_EXISTS;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_BUILDIN_OPERATION_PERMISSION_ERROR;
import static com.cf.imes.module.report.enums.ErrorCodeConstants.DATASOURCE_NOT_EXISTS;

/**
 * 报表数据集 Service 实现类
 *
 * @author Gqr
 * @since 2024/7/8 11:01
 */
@Service
@Validated
public class ReportDatasetServiceImpl implements ReportDatasetService {
    @Resource
    private ReportDatasourceMapper reportDatasourceMapper;

    @Resource
    private ReportDatasetMapper datasetMapper;

    @Override
    public Long createDataset(ReportDatasetSaveReqVO createReqVO) {
        // 校验内置模板操作权限
        ReportDatasourceDO reportDatasourceDO = validateSystemDataset(createReqVO.getDatasourceId());
        // 插入
        ReportDatasetDO dataset = BeanUtils.toBean(createReqVO, ReportDatasetDO.class);
        // 数据集机构id和数据源统一
        dataset.setOrganId(reportDatasourceDO.getOrganId());
        datasetMapper.insert(dataset);
        // 返回
        return dataset.getId();
    }

    @Override
    public void updateDataset(ReportDatasetSaveReqVO updateReqVO) {
        // 校验内置模板操作权限
        ReportDatasourceDO reportDatasourceDO = validateSystemDataset(updateReqVO.getDatasourceId());
        // 校验存在
        validateDatasetExists(updateReqVO.getId());
        // 更新
        ReportDatasetDO updateObj = BeanUtils.toBean(updateReqVO, ReportDatasetDO.class);
        // 数据集机构id和数据源统一
        updateObj.setOrganId(reportDatasourceDO.getOrganId());
        datasetMapper.updateById(updateObj);
    }

    @Override
    public void deleteDataset(Long id) {
        // 校验存在
        ReportDatasetDO reportDatasetDO = validateDatasetExists(id);
        // 校验内置模板操作权限
        validateSystemDataset(reportDatasetDO.getDatasourceId());
        // 删除
        datasetMapper.deleteById(id);
    }

    private ReportDatasetDO validateDatasetExists(Long id) {
        ReportDatasetDO reportDatasetDO = datasetMapper.selectById(id);
        if (ObjectUtil.isNull(reportDatasetDO)) {
            throw new ServiceException(DATASET_NOT_EXISTS);
        } else {
            return reportDatasetDO;
        }
    }

    /**
     * 校验只有超管可以操作内置数据源
     *
     * @param datasourceId 数据源id
     */
    private ReportDatasourceDO validateSystemDataset(Long datasourceId) {
        ReportDatasourceDO reportDatasourceDO = null;
        boolean superAdmin = SecurityFrameworkUtils.isSuperAdmin();
        // 超管查所有，其他人查机构下
        if (superAdmin) {
            reportDatasourceDO = reportDatasourceMapper.selectById(datasourceId);
        } else {
            reportDatasourceDO = reportDatasourceMapper.selectNormalDatasourceById(datasourceId, SecurityFrameworkUtils.getUserOrganId());
        }
        if (ObjectUtil.isNull(reportDatasourceDO)) {
            throw new ServiceException(DATASOURCE_NOT_EXISTS);
        }
        // 非超管不能操作内置模板
        if (ReportTemplateTypeEnum.SYSTEM.equals(reportDatasourceDO.getBuildinType()) && Boolean.FALSE.equals(superAdmin)) {
            throw new ServiceException(DATASOURCE_BUILDIN_OPERATION_PERMISSION_ERROR);
        }
        return reportDatasourceDO;
    }

    @Override
    public ReportDatasetDO getDataset(Long id) {
        return datasetMapper.selectById(id);
    }

    @Override
    public List<ReportDatasetDO> getDatasetList(ReportDatasetReqVO reqVO, Long organId) {
        return datasetMapper.selectList(new LambdaQueryWrapperX<ReportDatasetDO>()
                .eq(ReportDatasetDO::getOrganId, organId)
                .eqIfPresent(ReportDatasetDO::getDatasourceId, reqVO.getDatasourceId())
                .likeIfPresent(ReportDatasetDO::getName, reqVO.getName())
                .orderByDesc(ReportDatasetDO::getCreateTime));
    }
}
