package com.palmnest.webapp.controller;

import com.palmnest.application.Constants;
import com.palmnest.application.bean.AppResultDto;
import com.palmnest.application.bean.Pagenation;
import com.palmnest.application.core.util.AppResultUtil;
import com.palmnest.application.dto.output.AppFunctionOutDto;
import com.palmnest.model.AppFunction;
import com.palmnest.model.Role;
import com.palmnest.model.RoleFunction;
import com.palmnest.model.User;
import com.palmnest.service.AppFunctionManager;
import com.palmnest.service.AppMenuManager;
import com.palmnest.service.RoleManager;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ExtendedModelMap;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * 系统功能点Controller
 *
 * @author yb
 * @since 2014-05-28
 */
@Slf4j
@Controller
@RequestMapping("/admin/function/*")
public class AppFunctionController extends BaseFormController {

	private AppFunctionManager appFunctionManager;

	@Autowired
	public void setAppFunctionService(AppFunctionManager appFunctionManager) {
		this.appFunctionManager = appFunctionManager;
	}

	@Autowired
	private AppMenuManager appMenuManager;

	@Autowired
	private RoleManager roleManager;

	//TODO 默认列表查询
	@RequestMapping(value = "/list")
	public ModelAndView handleRequest(HttpServletRequest request,
									  HttpServletResponse response) throws Exception {
		initFunctionOperate(request);       //初始化功能操作权限

		Model           model        = new ExtendedModelMap();
		List<Criterion> filterList   = new ArrayList<Criterion>();
		String          pageNo       = request.getParameter("pageNo");
		String          functionName = request.getParameter("functionName");
		if (StringUtils.isNotEmpty(functionName)) {
			filterList.add(Restrictions.like("functionName", "%" + functionName + "%"));
			request.setAttribute("functionName", functionName);
		}
		if (StringUtils.isEmpty(pageNo)) {
			pageNo = "1";
		}
		Pagenation<AppFunction> pagenation = appFunctionManager.queryAppFunction(Integer.parseInt(pageNo), filterList);
		model.addAttribute("page", pagenation);
		return new ModelAndView("admin/appFuncList", model.asMap());
	}

	//TODO 默认新增和更新操作
	@RequestMapping(value = "/form")
	public ModelAndView formRequest(@ModelAttribute("appFunction") AppFunction appFunction, HttpServletRequest request,
									HttpServletResponse response) throws Exception {
		Model  model   = new ExtendedModelMap();
		String actType = request.getParameter("actType");//

		try {
			//新增或者更新
			if ("save".equals(actType)) {
				if (appFunction.getSystemcode() != null) {
					int    code = appFunction.getSystemcode();
					String id   = "";
					if (appFunction.getId() != null) {
						id = appFunction.getId().toString();
					}
					AppFunction function = appFunctionManager.getFuctionBySysCode(id, String.valueOf(code));
					if (function != null) {
						model.addAttribute("errormsg", "系统编码不能重复");
						model.addAttribute("funcid", request.getParameter("funcid"));
						return new ModelAndView("admin/appFuncForm", model.asMap());
					}
				}
				appFunction.setParentcode("-1");
				appFunction.setLastupdatetime(new Date());
				appFunction.setStatus(1);
				//更新
				if (appFunction.getId() != null) {
//					AppFunction app=appFunctionManager.getById(appFunction.getId());
//					appFunction.setSystemcode(appFunction.getSystemcode());
					appFunctionManager.updateObj(appFunction);
					model.addAttribute("errormsg", "更新成功");
				}
				//新增
				else {
					appFunctionManager.saveObj(appFunction);
					model.addAttribute("errormsg", "新增成功");
				}
			}
		} catch (Exception e) {
			model.addAttribute("errormsg", "失败:" + e.getMessage());
		}

		model.addAttribute("funcid", request.getParameter("funcid"));
		return new ModelAndView("admin/appFuncForm", model.asMap());
	}

	/**
	 * 更新
	 *
	 * @param id
	 * @param model
	 * @return
	 */
	@RequestMapping(value = "/update/{id}&{funcid}")
	public String update(@PathVariable int id, @PathVariable long funcid, Model model) {
		model.addAttribute(appFunctionManager.getById(id));
		model.addAttribute("funcid", funcid);
		return "admin/appFuncForm";
	}

	/**
	 * 删除
	 *
	 * @param id
	 * @return
	 */
	@RequestMapping(value = "/delete/{id}&{funcid}")
	public String delete(@PathVariable int id, @PathVariable long funcid) {
		AppFunction function = appFunctionManager.getById(id);
		try {
			appFunctionManager.remove(function);
		} catch (Exception e) {
			log.error("AppFunctionController delete() error ===========> " + e.getMessage());
		}
		return "redirect:/admin/function/list?funcid=" + funcid;
	}

	/**
	 * 删除
	 *
	 * @return
	 */
	@RequestMapping(value = "/deleteFuncTion", method = RequestMethod.POST, produces = "application/json")
	@ResponseBody
	public AppResultDto deleteFuncTion(HttpServletRequest request) {

		String id = request.getParameter("id");
		if (StringUtils.isBlank(id)) {
			return AppResultUtil.createErrorDto("100", "功能id不能为空");
		}

		AppFunction function = appFunctionManager.getById(Integer.parseInt(id));
		try {
			appFunctionManager.remove(function);
		} catch (Exception e) {
			log.error("AppFunctionController deleteFuncTion() error ===========> " + e.getMessage());
		}
		return AppResultUtil.createSuccesDto();
	}

	/**
	 * 查询
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "getFunction", method = RequestMethod.POST, produces = "application/json")
	@ResponseBody
	public AppResultDto getMenu(HttpServletRequest request,
								HttpServletResponse response) {
		String funcId = request.getParameter("funcId");

		if (StringUtils.isBlank(funcId)) {
			return AppResultUtil.createErrorDto("100", "功能id不能为空");
		}

		AppFunction function = appFunctionManager.getById(Integer.parseInt(funcId));

		AppFunctionOutDto obj = new AppFunctionOutDto();
		obj.setId(function.getId());//功能id
		obj.setFunctionName(function.getFunctionName());//功能名称
		obj.setTreecode(function.getTreecode());//节点
		obj.setParentcode(function.getParentcode());//父节点
		obj.setIsApp(function.getIsApp());//是否app
		obj.setOrderNumber(function.getOrderNumber());//排序号
		obj.setPerms(function.getPerms());//权限
		obj.setRightType(function.getRightType());
		obj.setSystemcode(function.getSystemcode());//功能编码
		obj.setUrl(function.getUrl());

		return AppResultUtil.createSuccesDto(obj);
	}

	/**
	 * longmeizhen判断系统编码不能重复
	 *
	 * @param request
	 * @param response
	 * @return
	 */
	@RequestMapping(value = "isFuncSysCode")
	@ResponseBody
	public AppResultDto isFuncSysCode(HttpServletRequest request, HttpServletResponse response) {
		String      id       = request.getParameter("id");
		String      sysCode  = request.getParameter("sysCode");
		AppFunction function = appFunctionManager.getFuctionBySysCode(id, sysCode);
		if (function == null) {
			return AppResultUtil.createSuccesDto("");
		}
		return AppResultUtil.createErrorDto("100", "已存在该系统编码，不允许重复设置");
	}


	/**
	 * 新增或更新
	 *
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/saveOrUpdate")
	@ResponseBody
	public AppResultDto saveOrUpdate(@ModelAttribute("appFunction") AppFunction appFunction, HttpServletRequest request,
									 HttpServletResponse response) throws Exception {

		User user = (User) request.getSession().getAttribute("UserCache");//获取当前登录用户

		//先校验功能编码  不能重复
		if (appFunction.getSystemcode() != null) {
			int    code = appFunction.getSystemcode();
			String id   = "";
			if (appFunction.getId() != null) {
				id = appFunction.getId().toString();
			}
			AppFunction function = appFunctionManager.getFuctionBySysCode(id, String.valueOf(code));
			if (function != null) {
				return AppResultUtil.createErrorDto("100", "功能编码不能重复");
			}
		}

		//校验权限字段perms不能重复
		if (StringUtils.isNotBlank(appFunction.getPerms())) {
			String perms = appFunction.getPerms();
			String id    = "";
			if (appFunction.getId() != null) {
				id = appFunction.getId().toString();
			}
			AppFunction function = appFunctionManager.getFuctionByPerms(id, perms);
			if (function != null && appFunction.getParentcode().equals(function.getParentcode())) {//同一个功能权限的子权限字符串不能重复
				return AppResultUtil.createErrorDto("100", "功能权限不能重复");
			}
		}

		//非空字段校验
		if (StringUtils.isBlank(appFunction.getFunctionName())) {
			return AppResultUtil.createErrorDto("100", "功能名称不能为空");
		}

		appFunction.setLastupdatetime(new Date());//更新时间
		appFunction.setLastupdateby(user.getId().intValue());//操作人
		appFunction.setStatus(1);//设置状态

		//新增或更新操作
		if (appFunction.getId() == null) {
			//新增
			appFunctionManager.saveObj(appFunction);
			appFunction.setTreecode(appFunction.getId().toString());//设置TreeCode
		} else {
			appFunction.setTreecode(appFunction.getId() + "");
		}

		appFunctionManager.updateObj(appFunction);

		return AppResultUtil.createSuccesDto();
	}


	/**
	 * 获取功能列表
	 *
	 * @param request
	 * @param response
	 * @return
	 * @throws Exception
	 */
	@RequestMapping(value = "/funcList")
	@ResponseBody
	public AppResultDto funcList(HttpServletRequest request, HttpServletResponse response) {

		String isApp = "0";//设置默认值为0
		isApp = request.getParameter("isApp");//0-PC 1-APP

		List<AppFunction>       functions     = appFunctionManager.getAll(Integer.parseInt(isApp));//获取功能列表
		List<AppFunctionOutDto> functionTrees = new ArrayList<AppFunctionOutDto>();
		for (AppFunction function : functions) {
			AppFunctionOutDto obj = new AppFunctionOutDto();
			obj.setId(function.getId());//功能id
			obj.setFunctionName(function.getFunctionName());//功能名称
			obj.setTreecode(function.getTreecode());//节点
			obj.setParentcode(function.getParentcode());//父节点
			obj.setIsApp(function.getIsApp());//是否app
			obj.setOrderNumber(function.getOrderNumber());//排序号
			obj.setPerms(function.getPerms());//权限
			obj.setRightType(function.getRightType());
			obj.setSystemcode(function.getSystemcode());//功能编码
			obj.setUrl(function.getUrl());
			functionTrees.add(obj);
		}

		AppFunctionOutDto obj = new AppFunctionOutDto();
		obj.setId(0);//功能id
		obj.setFunctionName("所有功能");//功能名称
		obj.setParentcode("-1");//父节点
		obj.setIsApp(Integer.parseInt(isApp));//是否app端功能
		obj.setPerms(Integer.parseInt(isApp) == 0 ? "pc" : "app");
		functionTrees.add(obj);

		return AppResultUtil.createSuccesDto(functionTrees);
	}


	/**
	 * --新增或编辑角色时
	 * 根据项目查询系统功能列表
	 * <p>
	 * --如果当前操作用户为超级管理员,则他应该查询到所有的功能列表
	 * 如果当前操作用户为项目管理员或者普通管理员,则他只能查询到自己角色下所拥有的功能列表
	 *
	 * @param request consumes
	 */
	@RequestMapping(value = "funcRoletreeByOrg", produces = "application/json")
	public @ResponseBody
	AppResultDto queryAppFunctionTreeByOrg(HttpServletRequest request) {
		User user = (User) request.getSession().getAttribute("UserCache");

		List<AppFunction> functions = new ArrayList<AppFunction>();
		//获取角色id
		String roleid = request.getParameter("roleid");
		//哪个端 0-PC 1-APP
		String isApp = request.getParameter("isApp");//0-PC 1-APP

		if (user.getUserType() < Constants.USER_TYPE_PROJECT_MANAGE) {
			//如果是系统管理员及以上角色,则加载所有功能
			functions = appFunctionManager.getAll(Integer.parseInt(isApp));//获取功能列表
		} else {
			//否则只加载其所对应角色的功能列表
			String orgId = request.getParameter("orgId");
			//获取其role集合
			Set<Role> roleSet = user.getRoles();
			for (Role role : roleSet) {
				if (StringUtils.isNotBlank(orgId)) {
					if (null == role.getOrgId() || role.getOrgId() != Integer.parseInt(orgId))
						continue;
				}
				//获取该角色对应的功能权限列表
				List<AppFunction> roleFunction = appFunctionManager.getFunctionListByRole(role.getId(), isApp);
				functions.addAll(roleFunction);

			}
		}

		//更新
		if (StringUtils.isNotEmpty(roleid)) {
			Role                    role       = roleManager.get(Long.parseLong(roleid));
			List<AppFunctionOutDto> outDtoList = filterShowFunction(functions, roleManager.queryRoleFunctionSet(role), isApp);
			return AppResultUtil.createSuccesDto(outDtoList);
		}
		//新增
		else {
			List<AppFunctionOutDto> outDtoList = filterShowFunction(functions, null, isApp);
			return AppResultUtil.createSuccesDto(outDtoList);
		}
	}

	/**
	 * 过滤筛选
	 *
	 * @param all
	 * @param roleWith
	 * @return
	 */
	public List<AppFunctionOutDto> filterShowFunction(List<AppFunction> all, List<RoleFunction> roleWith, String isApp) {
		List<AppFunctionOutDto> trees = new ArrayList<AppFunctionOutDto>();
		AppFunctionOutDto       obj1  = new AppFunctionOutDto();
		obj1.setId(0);//功能id
		obj1.setFunctionName("所有功能");//功能名称
		obj1.setParentcode("");//父节点
		obj1.setIsApp(Integer.parseInt(isApp));//是否app端功能
		trees.add(obj1);

		if (roleWith != null && roleWith.size() > 0) {
			for (AppFunction appFunction : all) {
				if (appFunction.getStatus() == 0) {
					continue;//禁用的功能不展示
				}
				AppFunctionOutDto obj = new AppFunctionOutDto();
				obj.setId(appFunction.getId());//功能id
				obj.setFunctionName(appFunction.getFunctionName());//功能名称
				obj.setTreecode(appFunction.getTreecode());//节点
				obj.setParentcode(appFunction.getParentcode());//父节点
				obj.setOrderNumber(appFunction.getOrderNumber());//排序号
				obj.setPerms(appFunction.getPerms());//权限
				obj.setRightType(appFunction.getRightType());
				obj.setSystemcode(appFunction.getSystemcode());//功能编码
				obj.setUrl(appFunction.getUrl());
				obj.setIsApp(Integer.parseInt(isApp));//是否app端功能
				for (Iterator<RoleFunction> iterator = roleWith.iterator(); iterator.hasNext(); ) {
					RoleFunction rolefunction = iterator.next();
					if (String.valueOf(rolefunction.getFunction().getId()).equals(String.valueOf(appFunction.getId()))) {
						obj.setChecked(true);
						break;
					}
				}
				trees.add(obj);
			}
		} else {
			for (AppFunction appFunction : all) {
				if (appFunction.getStatus() == 0) {
					continue;//禁用的功能不展示
				}
				AppFunctionOutDto obj = new AppFunctionOutDto();
				obj.setId(appFunction.getId());//功能id
				obj.setFunctionName(appFunction.getFunctionName());//功能名称
				obj.setTreecode(appFunction.getTreecode());//节点
				obj.setParentcode(appFunction.getParentcode());//父节点
				obj.setOrderNumber(appFunction.getOrderNumber());//排序号
				obj.setPerms(appFunction.getPerms());//权限
				obj.setRightType(appFunction.getRightType());
				obj.setSystemcode(appFunction.getSystemcode());//功能编码
				obj.setUrl(appFunction.getUrl());
				obj.setIsApp(Integer.parseInt(isApp));//是否app端功能
				obj.setChecked(false);
				trees.add(obj);
			}
		}
		return trees;
	}


	/**
	 * 对角色功能进行划分处理
	 * 接收二级功能id 为角色重新绑定三级功能关系
	 *
	 * @param request
	 */
	@RequestMapping("/sortFunc")
	public void sortFunc(HttpServletRequest request) {

		String funcId = request.getParameter("funcId");
		appFunctionManager.sortFunc(funcId);
	}
}
