package com.patzn.lims.sys.service.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.patzn.lims.core.api.PtAssert;
import com.patzn.lims.core.spring.I18nMessage;
import com.patzn.lims.core.web.Account;
import com.patzn.lims.core.web.BaseServiceImpl;
import com.patzn.lims.core.web.LoginHelper;
import com.patzn.lims.sys.entity.SysResource;
import com.patzn.lims.sys.mapper.SysResourceMapper;
import com.patzn.lims.sys.service.ISysResourceService;
import com.patzn.lims.sys.vo.SysResourceVO;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 资源表 服务实现类
 * </p>
 *
 * @author patzn
 * @since 2017-07-10
 */
@Service
@CacheConfig(cacheNames = {"resource"})
public class SysResourceServiceImpl extends BaseServiceImpl<SysResourceMapper, SysResource> implements ISysResourceService {


    @Override
    public Page<SysResourceVO> page(Page<SysResourceVO> page, SysResource sysResource) {
        // 菜单
        sysResource.setType(0);
        if (null != sysResource.getId()) {
            // 递归分页情况
            return pageRecursive(page, sysResource);
        }
        return page.setRecords(baseMapper.selectPageVo(page, sysResource));
    }


    @Override
    public Page<SysResourceVO> pageBtn(Page<SysResourceVO> page, SysResource sysResource) {
        // 按钮
        sysResource.setType(1);
        return page.setRecords(baseMapper.selectPageVo(page, sysResource));
    }


    @Override
    public Page<SysResourceVO> pageRecursive(Page<SysResourceVO> page, SysResource sysResource) {
        return page.setRecords(baseMapper.selectPageRecursive(page, sysResource));
    }


    @Override
    public List<String> listBtn(Account account) {
        Long userId = null;
        if (!LoginHelper.isSysAdmin()) {
            // 非管理员查看授权按钮
            userId = account.getUserId();
        }
        return baseMapper.selectListBtn(userId);
    }


    @Override
    public SysResourceVO getVoById(Long id) {
        return baseMapper.selectVoById(id);
    }


    @Override
    public List<SysResource> getMenuTree(SysResourceVO vo) {
        return baseMapper.selectMenuTree(vo);
    }


    @CacheEvict(value = "1hours", key = "'sysResource'")
    @Override
    public boolean updateById(SysResource entity) {
        return super.updateById(entity);
    }


    @CacheEvict(value = "1hours", key = "'sysResource'", beforeInvocation=true)
    @Override
    public boolean save(SysResource sysResource) {
        // 菜单
        sysResource.setType(0);
        sysResource.setStatus(1);
        return super.save(sysResource);
    }

    @Override
    public List<Object> getNavMenu(Long userId, String code) {
        return getNavMenuI18n(I18nMessage.isEnglish(), userId, code);
    }

    @Cacheable(value = "1hours", key = "'sysResource'")
    public List<Object> getNavMenuI18n(boolean english, Long userId, String code) {
        if (null == userId || null == code) {
            return null;
        }
        List<Object> ja = new ArrayList<>();
        List<SysResource> menuList = baseMapper.selectNavMenu(userId, code);
        if (CollectionUtils.isNotEmpty(menuList)) {
            for (SysResource srTab : menuList) {
                if (srTab.getPid().equals(0L)) {
                    // TAB 导航
                    Map<String, Object> tab = newJSONObject(english, srTab);
                    // 返回指定系统的资源菜单
                    if (code.equals(srTab.getCode())) {
                        List<Object> jaTab = new ArrayList<>();
                        for (SysResource srLeft : menuList) {
                            if (srLeft.getPid().equals(srTab.getId())) {
                                // 左侧 一级菜单
                                Map<String, Object> joLeft = newJSONObject(english, srLeft);
                                List<Object> jaLeft = new ArrayList<>();
                                for (SysResource srSub : menuList) {
                                    if (srSub.getPid().equals(srLeft.getId())) {
                                        // 左侧 二级菜单
                                        jaLeft.add(newJSONObject(english, srSub));
                                    }
                                }
                                joLeft.put("subMenus", jaLeft);
                                jaTab.add(joLeft);
                            }
                        }
                        tab.put("leftMenus", jaTab);
                    }
                    ja.add(tab);
                }
            }
        }
        return ja;
    }

    private Map<String, Object> newJSONObject(boolean english, SysResource sysResource) {
        Map<String, Object> jo = new HashMap<>(3);
        jo.put("id", sysResource.getId());
        jo.put("name", english ? sysResource.getEname() : sysResource.getName());
        jo.put("uri", sysResource.getUri());
        jo.put("code", sysResource.getCode());
        jo.put("icon", sysResource.getIcon());
        return jo;
    }


    @Override
    public List<SysResource> getAppMenu(Long userId) {
        return baseMapper.selectAppMenu(userId);
    }


    @Override
    public boolean saveBtn(Long menuId, SysResource sysResource) {
        verifyCode(sysResource);
        // 按钮
        sysResource.setType(1);
        sysResource.setStatus(1);
        SysResource sr = getById(menuId);
        sysResource.setPid(sr.getId());
        sysResource.setSystemId(sr.getSystemId());
        return super.save(sysResource);
    }


    /**
     * 角色名称校验
     */
    private void verifyCode(SysResource sysResource) {
        if (super.count(Wrappers.<SysResource>query().eq("code", sysResource.getCode())
                .ne(null != sysResource.getId(), "id", sysResource.getId())) > 0) {
            PtAssert.fail("抱歉!该编码已存在，重新输入。");
        }
    }


    @Override
    public SysResource getById(Serializable id) {
        SysResource sysResource = super.getById(id);
        if (null == sysResource) {
            PtAssert.fail("抱歉！菜单不存在刷新后重试。");
        }
        return sysResource;
    }
}
