package com.ozs.rpm.service.impl;

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

import com.ozs.rpm.service.MenuService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.ozs.rpm.dto.MenuDTO;
import com.ozs.rpm.dto.ReportDTO;
import com.ozs.rpm.dto.ReportKPIDTO;
import com.ozs.rpm.dto.ReportShowTypeDTO;
import com.ozs.rpm.mapper.MenuMapper;
import com.ozs.rpm.util.R;
import com.ozs.rpm.util.RandomUtil;

@Service
public class MenuServiceImpl implements MenuService {

	@Autowired
	private MenuMapper menuMapper;

	@Override
	public R<List<MenuDTO>> getMenuTree(String menuName) throws Exception {
		return new R<>(menuMapper.listMenuByName(menuName));
	}

	@Override
	public R<MenuDTO> getMenu(String menuCode) throws Exception {
		return new R<>(menuMapper.getMenuByCode(menuCode));
	}

	@Transactional
	@Override
	public R<String> updateMenu(MenuDTO menuDTO) throws Exception {
		R<String> r = new R<>();
		// 判断菜单名称是否重复
		MenuDTO m = menuMapper.getMenuByName(menuDTO.getMenuName());
		if (m != null && !m.getMenuCode().equals(menuDTO.getMenuCode())) {
			r.setCode("-1");
			r.setMsg("菜单名称已存在");
			return r;
		}
		// 更新分类信息
		menuMapper.updateMenu(menuDTO);
		// 修改后的menuCode
		String newMenuCode = null;
		if (menuDTO.getPCode() != null) {
			newMenuCode = menuDTO.getPCode() + menuDTO.getMenuCode().substring(menuDTO.getMenuCode().length() - 4,
					menuDTO.getMenuCode().length());
		}
		// 判断是否修改了PCode，修改Pcode则更新menuCode和其下所有子类code
		if (newMenuCode != null && !menuDTO.getMenuCode().equals(newMenuCode)) {
			menuMapper.updateMenusCode(menuDTO.getMenuCode(), newMenuCode);
		}
		r.setData("修改成功");
		return r;
	}

	@Transactional
	@Override
	public R<String> saveMenu(MenuDTO menuDTO) throws Exception {
		R<String> r = new R<>();
		// 判断菜单名称是否重复
		if (menuMapper.getMenuByName(menuDTO.getMenuName()) != null) {
			r.setCode("-1");
			r.setMsg("菜单名称已存在");
			return r;
		}

		// TODO 判断菜单编号是否重复
		// 判断新建菜单是否为第一级菜单
		if (menuDTO.getPCode() == null || menuDTO.getPCode().equals("0")) {
			menuDTO.setMenuCode(RandomUtil.generateShortUuid());
			menuDTO.setMenuLevel(1);
		} else {
			MenuDTO m = menuMapper.getMenuByCode(menuDTO.getPCode());
			menuDTO.setMenuCode(menuDTO.getPCode() + RandomUtil.generateShortUuid());
			menuDTO.setMenuLevel(m.getMenuLevel() + 1);
			// 判断父节点是否为叶子节点，叶子节点则修改状态为非叶子节点
			if (menuMapper.getIfLeafNodeByCode(menuDTO.getPCode()) == 1) {
				MenuDTO pMenuDTO = new MenuDTO();
				pMenuDTO.setMenuCode(menuDTO.getPCode());
				pMenuDTO.setIfLeafNode(0);
				menuMapper.updateMenuIfLeafNode(pMenuDTO);
			}
		}
		// 默认新建为叶子节点
		menuDTO.setIfLeafNode(1);
		menuMapper.saveMenu(menuDTO);
		r.setData("添加成功");
		return r;
	}

	@Override
	public R<String> removeMenu(String menuCode) throws Exception {
		R<String> r = new R<>();
		MenuDTO menuDTO = menuMapper.getMenuByCode(menuCode);
		// 判断菜单下及子菜单是否存在报表
		if (menuMapper.countMenuReportNotNull(menuCode) != 0) {
			r.setCode("-1");
			r.setMsg("菜单下存在报表，不可删除");
			return r;
		}

		// 判断父类菜单是否还有其他子集，不存在则修改父类菜单为叶子节点
		// if (menuMapper.countBroMenuByCode(menuCode) == 0) {
		// MenuDTO pMenuDTO = new MenuDTO();
		// pMenuDTO.setMenuCode(menuDTO.getPCode());
		// pMenuDTO.setIfLeafNode(1);
		// menuMapper.updateMenuIfLeafNode(pMenuDTO);
		// }
		menuMapper.removeMenuByCode(menuCode);
		// 删除报表分类关联关系
		menuMapper.removeRpmInfoReportMenuByMenuId(menuDTO.getId());

		r.setData("删除成功");
		return r;
	}

	@Override
	public R<List<ReportShowTypeDTO>> listShowType() throws Exception {
		return new R<>(new ArrayList<>());
	}

	@Override
	public R<List<MenuDTO>> getMenuTreeOnlyLeaf() throws Exception {
		return new R<>(menuMapper.listLeafMenu());
	}

	@Override
	public R<String> saveReportBasicInfo(ReportDTO reportDTO) throws Exception {
		return new R<>();
	}

	@Override
	public R<String> saveReportKPI(ReportKPIDTO reportKPIDTO) throws Exception {
		return new R<>();
	}

	@Override
	public R<List<MenuDTO>> listMenuTreeOnlyLeaf(String menuName, String reportId) {
		return new R<>(menuMapper.listMenuTreeOnlyLeaf(menuName, reportId));
	}

}
