
package com.tmerclub.cloud.platform.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.crypto.digest.DigestAlgorithm;
import cn.hutool.crypto.digest.Digester;
import com.tmerclub.cloud.api.auth.constant.SysTypeEnum;
import com.tmerclub.cloud.api.platform.vo.SysAccessKeyVO;
import com.tmerclub.cloud.api.platform.vo.UriPermissionVO;
import com.tmerclub.cloud.api.rbac.bo.UriPermissionBO;
import com.tmerclub.cloud.api.rbac.feign.PermissionFeignClient;
import com.tmerclub.cloud.common.cache.constant.PlatformCacheNames;
import com.tmerclub.cloud.common.database.dto.PageDTO;
import com.tmerclub.cloud.common.database.util.PageUtil;
import com.tmerclub.cloud.common.database.vo.PageVO;
import com.tmerclub.cloud.common.exception.LuckException;
import com.tmerclub.cloud.common.leaf.manager.SegmentManager;
import com.tmerclub.cloud.common.util.BeanUtil;
import com.tmerclub.cloud.constant.DistributedIdKey;
import com.tmerclub.cloud.platform.dto.SysAccessKeyDTO;
import com.tmerclub.cloud.platform.mapper.SysAccessKeyMapper;
import com.tmerclub.cloud.platform.mapper.SysAccessMenuMapper;
import com.tmerclub.cloud.platform.mapper.SysAccessMenuPermissionMapper;
import com.tmerclub.cloud.platform.model.SysAccessKey;
import com.tmerclub.cloud.platform.model.SysAccessMenuPermission;
import com.tmerclub.cloud.platform.service.SysAccessKeyService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

/**
 * 系统密钥
 * @author TRACK
 */
@Service
public class SysAccessKeyServiceImpl implements SysAccessKeyService {

    @Autowired
    private SysAccessKeyMapper sysAccessKeyMapper;
    @Autowired
    private SegmentManager segmentManager;
    @Autowired
    private SysAccessMenuMapper sysAccessMenuMapper;
    @DubboReference
    private PermissionFeignClient permissionFeignClient;
    @Autowired
    private SysAccessMenuPermissionMapper sysAccessMenuPermissionMapper;

    @Override
    public PageVO<SysAccessKey> page(PageDTO pageDTO, SysAccessKeyDTO sysAccessKeyDTO) {
        return PageUtil.doPage(pageDTO, () -> sysAccessKeyMapper.list(sysAccessKeyDTO));
    }

    @Override
    public SysAccessKeyVO getBySysAccessKeyId(Long sysAccessKeyId) {
        SysAccessKeyVO sysAccessKeyVO = sysAccessKeyMapper.getBySysAccessKeyId(sysAccessKeyId);
//        //查询角色对应的菜单
//        List<Long> menuList = sysAccessMenuMapper.listMenuIdAccessId(sysAccessKeyId);
//        sysAccessKey.setMenuIdList(menuList);
        return sysAccessKeyVO;
    }

    @Override
    @CacheEvict(cacheNames = PlatformCacheNames.SYS_ACCESS_KEY, key = "#sysAccessKeyDTO.accessId")
    @Transactional(rollbackFor = Exception.class)
    public void save(SysAccessKeyDTO sysAccessKeyDTO) {
        SysAccessKey sysAccessKey = BeanUtil.map(sysAccessKeyDTO, SysAccessKey.class);
        Long accessId = segmentManager.getSegmentId(DistributedIdKey.tmerclub_AUTHORIZATION);
        sysAccessKeyDTO.setAccessId(String.valueOf(accessId));
        sysAccessKey.setAccessId(String.valueOf(accessId));
        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
        sysAccessKey.setAccessKey(sha256.digestHex(sysAccessKey.getAccessId() + System.currentTimeMillis()));
        sysAccessKeyMapper.save(sysAccessKey);
        if (Objects.isNull(sysAccessKeyDTO.getMenuIdList())) {
            return;
        }
        // 保存与菜单关系
        sysAccessMenuMapper.insertAccessKeyAndMenu(sysAccessKey.getSysAccessKeyId(), sysAccessKeyDTO.getMenuIdList());
        sysAccessMenuPermissionMapper.saveSysAccessMenuPerms(sysAccessKey.getSysAccessKeyId(), sysAccessKeyDTO.getMenuPermissionId());
    }

    @Override
    @CacheEvict(cacheNames = PlatformCacheNames.SYS_ACCESS_KEY, key = "#sysAccessKeyDTO.accessId")
    @Transactional(rollbackFor = Exception.class)
    public void update(SysAccessKeyDTO sysAccessKeyDTO) {
        SysAccessKey sysAccessKey = BeanUtil.map(sysAccessKeyDTO, SysAccessKey.class);
        SysAccessKey accessKey = new SysAccessKey();
        accessKey.setSysAccessKeyId(sysAccessKey.getSysAccessKeyId());
        accessKey.setName(sysAccessKey.getName());
        accessKey.setRemark(sysAccessKey.getRemark());
        accessKey.setSysType(sysAccessKey.getSysType());
        accessKey.setRemark(sysAccessKey.getRemark());
        accessKey.setPremType(sysAccessKey.getPremType());
        accessKey.setUsabilityShopId(sysAccessKey.getUsabilityShopId());
        if(!Objects.equals(sysAccessKey.getSysType(),SysTypeEnum.MULTISHOP.value())){
            accessKey.setUsabilityShopId(0L);
        }
        sysAccessKeyMapper.update(accessKey);
        // 先删除角色与菜单关系
        sysAccessMenuMapper.deleteSysAccessMenuById(sysAccessKey.getSysAccessKeyId());
        // 保存与菜单关系
        sysAccessMenuMapper.insertAccessKeyAndMenu(sysAccessKey.getSysAccessKeyId(), sysAccessKeyDTO.getMenuIdList());
        // 删除密钥与菜单资源关系
        sysAccessMenuPermissionMapper.deletSysAccessMenuPermsBySysAccessKeyId(sysAccessKey.getSysAccessKeyId());
        // 保存密钥与菜单资源关系
        sysAccessMenuPermissionMapper.saveSysAccessMenuPerms(sysAccessKey.getSysAccessKeyId(), sysAccessKeyDTO.getMenuPermissionId());
    }

    @Override
    public void deleteById(Long sysAccessKeyId) {
        sysAccessKeyMapper.deleteById(sysAccessKeyId);
    }

    @Override
    @CacheEvict(cacheNames = PlatformCacheNames.SYS_ACCESS_KEY, key = "#accessId")
    public void removeCacheById(String accessId) {
    }

    @Override
    public void resetAccessKey(Long sysAccessKeyId) {
        SysAccessKeyVO sysAccessKey = sysAccessKeyMapper.getBySysAccessKeyId(sysAccessKeyId);
        if (Objects.isNull(sysAccessKey)) {
            throw new LuckException("此数据已被删除");
        }
        Digester sha256 = new Digester(DigestAlgorithm.SHA256);
        sysAccessKey.setAccessKey(sha256.digestHex(sysAccessKey.getAccessId() + System.currentTimeMillis()));
        sysAccessKeyMapper.update(BeanUtil.map(sysAccessKey, SysAccessKey.class));
    }

    @Override
    @Cacheable(cacheNames = PlatformCacheNames.SYS_ACCESS_KEY, key = "#accessId")
    public SysAccessKeyVO getByAccessId(String accessId) {
        SysAccessKeyVO sysAccessKeyVO = sysAccessKeyMapper.getByAccessId(accessId);
        if (Objects.isNull(sysAccessKeyVO)) {
            return new SysAccessKeyVO();
        }

        // 获取perms
        List<Long > menuIdList = sysAccessMenuPermissionMapper.queryMenuPermsBySysAccessKeyId(sysAccessKeyVO.getSysAccessKeyId());

        if(CollectionUtil.isEmpty(menuIdList)){
            return sysAccessKeyVO;
        }
        List<UriPermissionBO> premsList = permissionFeignClient.getUriPermissionListByMenuPermIdList(menuIdList).getData();
        List<UriPermissionVO> uriPermissionVOList = new ArrayList<>();
        for (UriPermissionBO uriPermissionBO : premsList) {
            uriPermissionVOList.add(BeanUtil.map(uriPermissionBO, UriPermissionVO.class));
        }
        sysAccessKeyVO.setPrems(uriPermissionVOList);
        return sysAccessKeyVO;
    }
}
