package cn.axzo.workflow.admin.service.impl;

import cn.axzo.basics.common.constant.enums.TableIsDeleteEnum;
import cn.axzo.framework.domain.ServiceException;
import cn.axzo.workflow.admin.repository.entity.ExtAxProcessAdmin;
import cn.axzo.workflow.admin.repository.mapper.ExtAxProcessAdminMapper;
import cn.axzo.workflow.admin.service.ExtAxProcessAdminService;
import cn.axzo.workflow.common.enums.AdminDataSource;
import cn.axzo.workflow.common.enums.AdminTypeEnum;
import cn.axzo.workflow.common.model.request.admin.ProcessAdminDeleteDTO;
import cn.axzo.workflow.common.model.request.admin.ProcessAdminQueryDTO;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

@Service
public class ExtAxProcessAdminServiceImpl implements ExtAxProcessAdminService {

    @Resource
    private ExtAxProcessAdminMapper extAxProcessAdminMapper;

    @Override
    public Long insert(ExtAxProcessAdmin processAdmin) {
        extAxProcessAdminMapper.insert(processAdmin);
        return processAdmin.getId();
    }

    @Override
    public void batchInsert(List<ExtAxProcessAdmin> processAdmins) {
        if (CollectionUtils.isEmpty(processAdmins)) {
            return;
        }
        processAdmins.forEach(this::insert);
    }

    @Override
    public List<ExtAxProcessAdmin> query(ProcessAdminQueryDTO queryDTO) {
        if (queryDTO == null) {
            return Collections.emptyList();
        }
        return extAxProcessAdminMapper.selectList(getQueryWrapper(queryDTO));
    }


    @Override
    public Integer queryCount(ProcessAdminQueryDTO queryDTO) {
        return extAxProcessAdminMapper.selectCount(getQueryWrapper(queryDTO));
    }

    @Override
    public Integer delete(ProcessAdminDeleteDTO deleteDTO) {
        if (deleteDTO == null) {
            return 0;
        }
        return extAxProcessAdminMapper.delete(getDeleteWrapper(deleteDTO));
    }

    @Override
    public Integer deleteCommonAdminsByIds(List<Long> ids) {
        if (CollectionUtils.isEmpty(ids)) {
            return 0;
        }
        List<ExtAxProcessAdmin> extAxProcessAdmins = extAxProcessAdminMapper.selectBatchIds(ids);
        if (CollectionUtils.isEmpty(extAxProcessAdmins)) {
            return 0;
        }
        validateDeleteCommonAdmins(extAxProcessAdmins);
        return extAxProcessAdminMapper.deleteBatchIds(ids);
    }

    private void validateDeleteCommonAdmins(List<ExtAxProcessAdmin> extAxProcessAdmins) {
        if (CollectionUtils.isEmpty(extAxProcessAdmins)) {
            return;
        }
        if (extAxProcessAdmins.stream().anyMatch(ad -> ad.getAdminType() == AdminTypeEnum.SUPER_ADMIN)) {
            throw new ServiceException("超级管理员不允许删除");
        }
        if (extAxProcessAdmins.stream().anyMatch(ad -> ad.getDataSource() == AdminDataSource.SYSTEM_ENTRY)) {
            throw new ServiceException("系统数据不允许删除");
        }
    }

    private LambdaQueryWrapper<ExtAxProcessAdmin> getQueryWrapper(ProcessAdminQueryDTO queryDTO) {
        return new LambdaQueryWrapper<ExtAxProcessAdmin>()
                .in(!CollectionUtils.isEmpty(queryDTO.getProcessAdminIds()), ExtAxProcessAdmin::getId, queryDTO.getProcessAdminIds())
                .eq(Objects.nonNull(queryDTO.getWorkspaceId()), ExtAxProcessAdmin::getWorkspaceId, queryDTO.getWorkspaceId())
                .eq(queryDTO.getAdminType() != null, ExtAxProcessAdmin::getAdminType, queryDTO.getAdminType())
                .eq(Objects.nonNull(queryDTO.getOrganizationalUnitId()), ExtAxProcessAdmin::getOrganizationalUnitId, queryDTO.getOrganizationalUnitId())
                .in(!CollectionUtils.isEmpty(queryDTO.getPersonIds()), ExtAxProcessAdmin::getPersonId, queryDTO.getPersonIds())
                .eq(Objects.nonNull(queryDTO.getDataSource()), ExtAxProcessAdmin::getDataSource, queryDTO.getDataSource())
                .eq(ExtAxProcessAdmin::getIsDelete, TableIsDeleteEnum.NORMAL.value);
    }

    private LambdaQueryWrapper<ExtAxProcessAdmin> getDeleteWrapper(ProcessAdminDeleteDTO deleteDTO) {
        return new LambdaQueryWrapper<ExtAxProcessAdmin>()
                .in(!CollectionUtils.isEmpty(deleteDTO.getProcessAdminIds()), ExtAxProcessAdmin::getId, deleteDTO.getProcessAdminIds())
                .eq(Objects.nonNull(deleteDTO.getWorkspaceId()), ExtAxProcessAdmin::getWorkspaceId, deleteDTO.getWorkspaceId())
                .eq(deleteDTO.getAdminType() != null, ExtAxProcessAdmin::getAdminType, deleteDTO.getAdminType())
                .eq(Objects.nonNull(deleteDTO.getOrganizationalUnitId()), ExtAxProcessAdmin::getOrganizationalUnitId, deleteDTO.getOrganizationalUnitId())
                .in(!CollectionUtils.isEmpty(deleteDTO.getWorkspaceIds()), ExtAxProcessAdmin::getWorkspaceId, deleteDTO.getWorkspaceIds())
                .in(!CollectionUtils.isEmpty(deleteDTO.getOrganizationalUnitIds()), ExtAxProcessAdmin::getOrganizationalUnitId, deleteDTO.getOrganizationalUnitIds())
                .in(!CollectionUtils.isEmpty(deleteDTO.getPersonIds()), ExtAxProcessAdmin::getPersonId, deleteDTO.getPersonIds())
                .eq(Objects.nonNull(deleteDTO.getDataSource()), ExtAxProcessAdmin::getDataSource, deleteDTO.getDataSource())
                .eq(ExtAxProcessAdmin::getIsDelete, TableIsDeleteEnum.NORMAL.value);
    }

}
