package com.dayou.service.impl;

import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.dayou.bo.PrivilegeTreeBO;
import com.dayou.common.BaseEntity;
import com.dayou.entity.Menu;
import com.dayou.entity.PostPrivilege;
import com.dayou.mapper.PostPrivilegeMapper;
import com.dayou.service.IMenuService;
import com.dayou.service.IPostPrivilegeService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dayou.utils.ConvertUtil;
import com.dayou.utils.TreeUtil;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.dayou.utils.ExcelUtil;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellStyle;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import java.util.List;
import java.util.ArrayList;
import org.springframework.transaction.annotation.Transactional;
import com.dayou.enums.BatchTaskTypeEnum;

/**
 * <p>
 * 岗位菜单权限 服务实现类
 * </p>
 *
 * @author wucl
 * @since 2022-11-29
 */
@Service
public class PostPrivilegeServiceImpl extends ServiceImpl<PostPrivilegeMapper, PostPrivilege> implements IPostPrivilegeService {

    private static final List<String> postPrivilegeExcelTitles= new ArrayList();

    static{
            postPrivilegeExcelTitles.add("权限树 json");
    }

    @Autowired
    private PostPrivilegeMapper postPrivilegeMapper;

    @Autowired
    private IMenuService menuService;

    @Override
    @SuppressWarnings("unchecked")
    public Page<PostPrivilege> selectPage(Page page,PostPrivilege postPrivilege){
        return this.page(page, new QueryWrapper<PostPrivilege>(postPrivilege));
    }


    @Override
    public PostPrivilege detail(Long id){
        return this.getById(id);
    }

    @Override
    public Boolean add(PostPrivilege postPrivilege){
        return  this.save(postPrivilege);
    }

    @Override
    public Boolean update(PostPrivilege postPrivilege){
        LambdaQueryWrapper<PostPrivilege> postPrivilegeQueryWrapper = new LambdaQueryWrapper<PostPrivilege>().eq(PostPrivilege::getPostId, postPrivilege.getPostId()).eq(BaseEntity::getDeleted, false);
        PostPrivilege privilege = this.getOne(postPrivilegeQueryWrapper);
        if (privilege == null){
            return this.save(postPrivilege);
        }
        return this.update(new LambdaUpdateWrapper<PostPrivilege>().set(PostPrivilege::getPermissionTree,postPrivilege.getPermissionTree())
                .eq(PostPrivilege::getPostId,postPrivilege.getPostId()));
    }

    @Override
    public Boolean delete(Long id){
        //逻辑删除
        return this.removeById(id);
    }

    @Override
    public XSSFWorkbook generateImportTemplate(){
        XSSFWorkbook wb = new XSSFWorkbook();
        //创建固定列的表头
        createExcelTitle(wb);
        return wb;
    }

    private void createExcelTitle(XSSFWorkbook wb) {
        Sheet sheet = wb.createSheet("岗位菜单权限导入模板");
        Row row = sheet.createRow(0);
        CellStyle style = wb.createCellStyle();
        Cell cell = null;
        for (int i = 0; i < postPrivilegeExcelTitles.size(); i++) {
            cell = row.createCell(i);
            cell.setCellStyle(style);
            cell.setCellValue(postPrivilegeExcelTitles.get(i));
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importExcel(MultipartFile file){
        ExcelUtil.importExcel(PostPrivilege.class, new ExcelUtil.ImportListener<PostPrivilege>() {
            @Override
            public Boolean handleOneRecord(PostPrivilege postPrivilege) {
                return add(postPrivilege);
            }

            @Override
            public void afterImport(ExcelUtil.BatchImportResult batchImportResult) {

            }
        }, file, BatchTaskTypeEnum.DEFAULT,ExcelUtil.BatchImportStrategy.ROLL_BACK);
    }

    @Override
    public XSSFWorkbook exportExcel(PostPrivilege postPrivilege) {
        XSSFWorkbook wb = ExcelUtil.export(PostPrivilege.class,
        (page, postPrivilegeReq) -> selectPage(page,postPrivilegeReq),
        postPrivilege);
        return wb;
    }

    @Override
    public void saveOrUpdateById(PostPrivilege postPrivilege) {
        postPrivilegeMapper.saveOrUpdateById(postPrivilege);
    }

    @Override
    public List<PrivilegeTreeBO> postPrivilegeTree(Long postId) {
        List<PrivilegeTreeBO> results = null;
        LambdaQueryWrapper<PostPrivilege> postPrivilegeLambdaQueryWrapper = new LambdaQueryWrapper<PostPrivilege>()
                .eq(PostPrivilege::getPostId, postId)
                .eq(PostPrivilege::getDeleted, false);
        PostPrivilege postPrivilege = this.getOne(postPrivilegeLambdaQueryWrapper);
        if (postPrivilege == null || (postPrivilege != null && StringUtils.isBlank(postPrivilege.getPermissionTree()))) {//如果没有配置过岗位权限，则生成一个空tree返回
            results = this.privilegeInitTree();
        } else {
            String tree = postPrivilege.getPermissionTree();
            Gson gson = new Gson();
            results=gson.fromJson(tree,new TypeToken<List<PrivilegeTreeBO>>(){}.getType());
            //将树平铺后进行菜单有效性过滤,然后再转回树
            results = (List<PrivilegeTreeBO>) TreeUtil.treeTile(results);
            //同步菜单
            results = (List<PrivilegeTreeBO>) menuService.syncMenu(results);
            //重新生成树
            results = (List<PrivilegeTreeBO>) TreeUtil.buildTree(results);
        }
        return results;
    }

    @Override
    public List<PrivilegeTreeBO> privilegeInitTree() {
        List<Menu> allMenus =  menuService.menuList();
        List<PrivilegeTreeBO> results = null;

        if(CollectionUtils.isNotEmpty(allMenus)){
            results = ConvertUtil.copyList(allMenus, menu -> {
                PrivilegeTreeBO privilegeTreeBO = new PrivilegeTreeBO();
                privilegeTreeBO.setName(menu.getName());
                privilegeTreeBO.setParentId(menu.getParentId());
                privilegeTreeBO.setId(menu.getId());
                privilegeTreeBO.setMenuType(menu.getMenuType());
                privilegeTreeBO.setChecked(false);
                privilegeTreeBO.setPcUrl(menu.getPcUrl());
                privilegeTreeBO.setPcIcon(menu.getPcIcon());
                privilegeTreeBO.setMenuNo(menu.getMenuNo());
                privilegeTreeBO.setMenuCode(menu.getMenuCode());
                privilegeTreeBO.setCachedViews(menu.getCachedViews());
                privilegeTreeBO.setOrderNum(menu.getOrderNum()!=null?menu.getOrderNum():0);
                return privilegeTreeBO;
            });
            results = (List<PrivilegeTreeBO>) TreeUtil.buildTree(results);
        }
        return results;
    }
}
