package com.zt.plat.module.qms.business.config.service;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigPermissionPageReqVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigPermissionRespVO;
import com.zt.plat.module.qms.business.config.controller.vo.ConfigPermissionSaveReqVO;
import org.springframework.stereotype.Service;
import jakarta.annotation.Resource;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import org.springframework.validation.annotation.Validated;

import java.util.*;

import com.zt.plat.module.qms.business.config.dal.dataobject.ConfigPermissionDO;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.common.util.object.BeanUtils;

import com.zt.plat.module.qms.business.config.dal.mapper.ConfigPermissionMapper;

import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.zt.plat.framework.common.exception.util.ServiceExceptionUtil.exception0;
import static com.zt.plat.framework.common.util.collection.CollectionUtils.convertList;
import static com.zt.plat.module.qms.enums.ErrorCodeConstants.*;

/**
 * 权限配置,通用权限配置 Service 实现类
 *
 * @author 后台管理
 */
@Service
@Validated
public class ConfigPermissionServiceImpl implements ConfigPermissionService {

    @Resource
    private ConfigPermissionMapper configPermissionMapper;


    /***
     * 保存权限，并判断删除
     * @param list： 传入的权限列表
     * 如果list为空，则按delSourceId、delSourceType、delPermissionType 删除
     *
     * */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePermissionListWithAutoDelete(List<ConfigPermissionSaveReqVO> list, Long delSourceId, String delSourceType, String delPermissionType) {
        LambdaQueryWrapper<ConfigPermissionDO> wrapper = new LambdaQueryWrapper<>();
        //如果传入权限列表为空，则按sourceId、 sourceType、 delPermissionType删除
        if(list == null || list.isEmpty()){
            if(delSourceId != null && !ObjectUtils.isEmpty(delSourceType)){
                wrapper.eq(ConfigPermissionDO::getSourceId, delSourceId);
                wrapper.eq(ConfigPermissionDO::getSourceType, delSourceType);
                if(delPermissionType != null)
                    wrapper.eq(ConfigPermissionDO::getPermissionType, delPermissionType);
                configPermissionMapper.delete( wrapper);
            }
            return;
        }
        //检查数据，避免误处理：按sourceId、sourceType检查
        List<Long> sourceIdList = list.stream().map(ConfigPermissionSaveReqVO::getSourceId).distinct().toList();
        List<String> sourceTypeList = list.stream().map(ConfigPermissionSaveReqVO::getSourceType).distinct().toList();
        List<String> permissionTypeList = list.stream().map(ConfigPermissionSaveReqVO::getPermissionType).distinct().toList();
        if (sourceIdList.size() > 1 || sourceTypeList.size() > 1 || permissionTypeList.size() > 1) {
            throw exception0(CONFIG_PERMISSION_DUPLICATE.getCode(), "权限保存失败，提交的权限数据存在不一致的情况，请刷新后重试，或联系管理员处理");
        }

        ConfigPermissionSaveReqVO queryDO = list.get(0);
        wrapper.eq(ConfigPermissionDO::getSourceId, queryDO.getSourceId())
                .eq(ConfigPermissionDO::getSourceType, queryDO.getSourceType());
        if(!ObjectUtils.isEmpty(queryDO.getPermissionType()))
            wrapper.eq(ConfigPermissionDO::getPermissionType, queryDO.getPermissionType());
        List<ConfigPermissionDO> oldList = configPermissionMapper.selectList(wrapper);
        List<ConfigPermissionSaveReqVO> insertList = new ArrayList<>();
        List<ConfigPermissionSaveReqVO> updateList = new ArrayList<>();
        List<Long> deleteIdList = new ArrayList<>();
        for (ConfigPermissionSaveReqVO newObj : list) {
            boolean exist = false;
            for (ConfigPermissionDO old : oldList) {
                if (old.getId().equals(newObj.getId())) {
                    exist = true;
                    if (!old.equals(newObj)) {
                        updateList.add(newObj);
                    }
                    break;
                }
            }
            if (!exist) {
                insertList.add(newObj);
            }
        }
        for (ConfigPermissionDO old : oldList) {
            boolean exist = false;
            for (ConfigPermissionSaveReqVO newObj : list) {
                if (old.getId().equals(newObj.getId())) {
                    exist = true;
                    break;
                }
            }
            if (!exist) {
                deleteIdList.add(old.getId());
            }
        }
        List<ConfigPermissionDO> list1 = new ArrayList<>();
        if(!insertList.isEmpty()){
            list1 = BeanUtils.toBean(insertList, ConfigPermissionDO.class);
            configPermissionMapper.insertBatch(list1);
        }
        if(!updateList.isEmpty()){
            list1 = BeanUtils.toBean(updateList, ConfigPermissionDO.class);
            configPermissionMapper.updateBatch(list1);
        }
        if(!deleteIdList.isEmpty())
            configPermissionMapper.deleteByIds(deleteIdList);


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void savePermission(List<ConfigPermissionDO> insertList, List<ConfigPermissionDO> updateList, List<Long> deleteList) {
        this.insertPermission(insertList);
        this.updatePermission(updateList);
        this.deletePermission(deleteList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void insertPermission(List<ConfigPermissionDO> insertList) {
        configPermissionMapper.insertBatch(insertList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePermission(List<ConfigPermissionDO> updateList) {
        configPermissionMapper.updateBatch(updateList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deletePermission(List<Long> deleteList) {
        configPermissionMapper.deleteByIds(deleteList);
    }

    @Override
    public List<ConfigPermissionDO> getPermissionList(Long sourceId, String sourceType, String permissionType) {
        LambdaQueryWrapper<ConfigPermissionDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ConfigPermissionDO::getSourceId, sourceId)
                .eq(ConfigPermissionDO::getSourceType, sourceType);
        if(!ObjectUtils.isEmpty(permissionType))
            queryWrapper.eq(ConfigPermissionDO::getPermissionType, permissionType);
        return configPermissionMapper.selectList(queryWrapper);
    }

    @Override
    public ConfigPermissionRespVO createConfigPermission(ConfigPermissionSaveReqVO createReqVO) {
        // 插入
        ConfigPermissionDO configPermission = BeanUtils.toBean(createReqVO, ConfigPermissionDO.class);
        configPermissionMapper.insert(configPermission);
        // 返回
        return BeanUtils.toBean(configPermission, ConfigPermissionRespVO.class);
    }

    @Override
    public void updateConfigPermission(ConfigPermissionSaveReqVO updateReqVO) {
        // 校验存在
        validateConfigPermissionExists(updateReqVO.getId());
        // 更新
        ConfigPermissionDO updateObj = BeanUtils.toBean(updateReqVO, ConfigPermissionDO.class);
        configPermissionMapper.updateById(updateObj);
    }

    @Override
    public void deleteConfigPermission(Long id) {
        // 校验存在
        validateConfigPermissionExists(id);
        // 删除
        configPermissionMapper.deleteById(id);
    }

    @Override
        public void deleteConfigPermissionListByIds(List<Long> ids) {
        // 校验存在
        validateConfigPermissionExists(ids);
        // 删除
        configPermissionMapper.deleteByIds(ids);
        }

    private void validateConfigPermissionExists(List<Long> ids) {
        List<ConfigPermissionDO> list = configPermissionMapper.selectByIds(ids);
        if (CollUtil.isEmpty(list) || list.size() != ids.size()) {
            throw exception(CONFIG_PERMISSION_NOT_EXISTS);
        }
    }

    private void validateConfigPermissionExists(Long id) {
        if (configPermissionMapper.selectById(id) == null) {
            throw exception(CONFIG_PERMISSION_NOT_EXISTS);
        }
    }

    @Override
    public ConfigPermissionDO getConfigPermission(Long id) {
        return configPermissionMapper.selectById(id);
    }

    @Override
    public PageResult<ConfigPermissionDO> getConfigPermissionPage(ConfigPermissionPageReqVO pageReqVO) {
        return configPermissionMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ConfigPermissionDO> getPermissionListByTargetIds(List<Long> targetIds) {

        return configPermissionMapper.selectList(Wrappers.lambdaQuery(ConfigPermissionDO.class)
                .in(ConfigPermissionDO::getTargetId, targetIds));
    }

}