package com.crm.manager.service.impl;

import com.crm.manager.dao.repository.SysActionRepository;
import com.crm.manager.dao.repository.SysNodeRepository;
import com.crm.manager.service.AuthorityService;
import com.crm.rely.backend.core.constant.Constants;
import com.crm.rely.backend.core.entity.system.action.SysActionAddEntity;
import com.crm.rely.backend.core.entity.system.action.SysActionDeleteEntity;
import com.crm.rely.backend.core.entity.system.action.SysActionUpdateEntity;
import com.crm.rely.backend.core.entity.system.node.SysNodeAddEntity;
import com.crm.rely.backend.core.entity.system.node.SysNodeDeleteEntity;
import com.crm.rely.backend.core.entity.system.node.SysNodeUpdateEntity;
import com.crm.rely.backend.core.pojo.table.SysActionTable;
import com.crm.rely.backend.core.pojo.table.SysNodeTable;
import com.crm.rely.backend.exception.ServiceException;
import com.crm.rely.backend.service.RedisService;
import com.crm.rely.backend.util.UUIDUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
public class AuthorityServiceImpl implements AuthorityService {

    @Autowired
    private SysActionRepository sysActionRepository;

    @Autowired
    private SysNodeRepository sysNodeRepository;

    @Autowired
    private RedisService redisService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysActionAddEntity entity) throws ServiceException {

        SysActionTable sysActionTable = new SysActionTable();
        BeanUtils.copyProperties(entity, sysActionTable);
        sysActionRepository.save(sysActionTable);
        updateRedisAuthorityIdentification();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SysActionDeleteEntity entity) throws ServiceException {
        List<SysActionTable> sysActionTables = sysActionRepository.findAllByIdIn(entity.getIds());

        if (sysActionTables == null || sysActionTables.size() <= 0) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        sysActionRepository.delete(sysActionTables);
        updateRedisAuthorityIdentification();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysActionUpdateEntity entity) throws ServiceException {
        SysActionTable sysActionTable = sysActionRepository.findFirstById(entity.getId());
        if (sysActionTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        BeanUtils.copyProperties(entity, sysActionTable);
        sysActionRepository.save(sysActionTable);
        updateRedisAuthorityIdentification();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void add(SysNodeAddEntity entity) throws ServiceException {
        SysNodeTable sysNodeTable = new SysNodeTable();
        BeanUtils.copyProperties(entity, sysNodeTable);
        sysNodeRepository.save(sysNodeTable);
        updateRedisAuthorityIdentification();
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(SysNodeDeleteEntity entity) throws ServiceException {
        List<SysNodeTable> sysNodeTables = sysNodeRepository.findAllByIdIn(entity.getIds());
        //递归出当前节点及下列节点
        sysNodeTables = getSysNodeTables(sysNodeTables);

        //判断节点及下列节点是否存在
        if (sysNodeTables != null && sysNodeTables.size() > 0) {
            List<Long> nodeIds = new ArrayList<>(sysNodeTables.size());
            for (SysNodeTable sysNodeTable :
                    sysNodeTables) {
                nodeIds.add(sysNodeTable.getId());
            }
            //查询节点下挂载的按钮
            List<SysActionTable> sysActionTables = sysActionRepository.findAllByNodeIdIn(nodeIds);
            if (sysActionTables != null || sysActionTables.size() >= 0) {

                //按钮如果存在 则一起删除
                sysActionRepository.delete(sysActionTables);
            }
            sysNodeRepository.delete(sysNodeTables);
            updateRedisAuthorityIdentification();
            return;
        }
        //如果选择的节点都不存在 则返回错误 通知到前端
        throw ServiceException.exception(Constants.INFO_NOT_FOUND);
    }

    private List<SysNodeTable> getSysNodeTables(List<SysNodeTable> sysNodeTables) {

        if (sysNodeTables == null || sysNodeTables.size() <= 0) {
            return null;
        }
        List<Long> ids = new ArrayList<>(sysNodeTables.size());
        for (SysNodeTable sysNodeTable :
                sysNodeTables) {
            ids.add(sysNodeTable.getId());
        }
        List<SysNodeTable> pidIn = sysNodeRepository.findAllByPidIn(ids);
        List<SysNodeTable> result = getSysNodeTables(pidIn);
        if (result != null) {
            sysNodeTables.addAll(result);
        }
        return sysNodeTables;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(SysNodeUpdateEntity entity) throws ServiceException {
        SysNodeTable sysNodeTable = sysNodeRepository.findFirstById(entity.getId());
        if (sysNodeTable == null) {
            throw ServiceException.exception(Constants.INFO_NOT_FOUND);
        }
        BeanUtils.copyProperties(entity, sysNodeTable);
        sysNodeRepository.save(sysNodeTable);
        updateRedisAuthorityIdentification();
    }

    /**
     * 更新redis中权限标识
     *
     * @throws ServiceException
     */
    @Override
    public String updateRedisAuthorityIdentification() throws ServiceException {
        String uuid = UUIDUtil.getUUID();
        redisService.saveObject(Constants.UPDATE_REDIS_AUTHORITY_IDENTIFICATION, uuid);
        return uuid;
    }
}
