/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.jeeplus.modules.sys.web;

import com.google.common.collect.Lists;
import com.jeeplus.common.json.AjaxJson;
import com.jeeplus.common.utils.StringUtils;
import com.jeeplus.config.properties.JeePlusProperites;
import com.jeeplus.core.web.BaseController;
import com.jeeplus.modules.sys.entity.Office;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.service.OfficeService;
import com.jeeplus.modules.sys.utils.DictUtils;
import com.jeeplus.modules.sys.utils.UserUtils;
import org.apache.shiro.authz.annotation.Logical;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.util.List;

/**
 * 机构Controller
 * @author jeeplus
 * @version 2019-5-15
 */
@RestController
@RequestMapping("/sys/office")
public class OfficeController extends BaseController {

	@Autowired
	private OfficeService officeService;

	@Autowired
	private JeePlusProperites jeePlusProperites;

	@ModelAttribute("office")
	public Office get(@RequestParam(required=false) String id) {
		if (StringUtils.isNotBlank(id)){
			return officeService.get(id);
		}else{
			return new Office();
		}
	}

	@RequiresPermissions("sys:office:list")
	@GetMapping(value ="list")
	public AjaxJson list(Office office, Model model) {
		if(office==null || office.getParentIds() == null){
			 return AjaxJson.success().put("list",  officeService.findList(false));
		}else{
			 return AjaxJson.success().put("list", officeService.findList(office));
		}
	}

	@RequiresPermissions(value={"sys:office:view","sys:office:add","sys:office:edit"},logical=Logical.OR)
	@GetMapping("queryById")
	public AjaxJson queryById(Office office) {
		User user = UserUtils.getUser();
		if (office.getParent()==null || office.getParent().getId()==null){
			office.setParent(user.getOffice());
		}
		office.setParent(officeService.get(office.getParent().getId()));
		if (office.getArea()==null){
			office.setArea(user.getOffice().getArea());
		}
		// 自动获取排序号
		if (StringUtils.isBlank(office.getId())&&office.getParent()!=null){
			int size = 0;
			List<Office> list = officeService.findAll();
			for (int i=0; i<list.size(); i++){
				Office e = list.get(i);
				if (e.getParent()!=null && e.getParent().getId()!=null
						&& e.getParent().getId().equals(office.getParent().getId())){
					size++;
				}
			}
			office.setCode(office.getParent().getCode() + StringUtils.leftPad(String.valueOf(size > 0 ? size+1 : 1), 3, "0"));
		}
		return AjaxJson.success().put("office", office);
	}

	@RequiresPermissions(value={"sys:office:add","sys:office:edit"},logical=Logical.OR)
	@PostMapping("save")
	public AjaxJson save(Office office, Model model) {
		if(jeePlusProperites.isDemoMode()){
			return AjaxJson.error("演示模式，不允许操作！");
		}
		/**
		 * 后台hibernate-validation插件校验
		 */
		String errMsg = beanValidator(office);
		if (StringUtils.isNotBlank(errMsg)){
			return AjaxJson.error(errMsg);
		}
		officeService.save(office);

		if(office.getChildDeptList()!=null){
			Office childOffice = null;
			for(String id : office.getChildDeptList()){
				childOffice = new Office();
				childOffice.setName(DictUtils.getDictLabel(id, "sys_office_common", "未知"));
				childOffice.setParent(office);
				childOffice.setArea(office.getArea());
				childOffice.setType("2");
				childOffice.setGrade(String.valueOf(Integer.valueOf(office.getGrade())+1));
				childOffice.setUseable(JeePlusProperites.YES);
				officeService.save(childOffice);
			}
		}
		return AjaxJson.success("保存机构'" + office.getName() + "'成功");
	}

	@RequiresPermissions("sys:office:del")
	@DeleteMapping("delete")
	public AjaxJson delete(Office office) {
		if(jeePlusProperites.isDemoMode()){
			return AjaxJson.error("演示模式，不允许操作！");
		}
		officeService.delete(office);
		return AjaxJson.success("删除成功！");
	}


	/**
	 * 获取机构JSON数据。
	 * @param extId 排除的ID
	 * @param type	类型（1：公司；2：部门/小组/其它）
	 * @param grade 显示级别
	 * @param response
	 * @return
	 */
	@RequiresPermissions("user")
	@GetMapping("treeData")
	public AjaxJson treeData(@RequestParam(required=false) String extId, @RequestParam(required=false) String type,
                                              @RequestParam(required=false) Long grade, @RequestParam(required=false) Boolean isAll, HttpServletResponse response) {
		List<Office> list = officeService.findList(isAll);
		List rootTree = getRootTree(list, extId, type, grade, isAll);
		return AjaxJson.success().put("treeData",rootTree);
	}

	private List<Office> getRootTree(List<Office> list, String extId, String type, Long grade, Boolean isAll) {
		List<Office> offices = Lists.newArrayList();
		List<Office> rootTrees = officeService.getChildren("0");
		for (Office root:rootTrees){
			if ((StringUtils.isBlank(extId) || (extId!=null && !extId.equals(root.getId()) && root.getParentIds().indexOf(","+extId+",")==-1))
					&& (type == null || (type != null && (type.equals("1") ? type.equals(root.getType()) : true)))
					&& (grade == null || (grade != null && Integer.parseInt(root.getGrade()) <= grade.intValue()))
					&& JeePlusProperites.YES.equals(root.getUseable())){
				offices.add(getChildOfTree(root, list, extId, type, grade, isAll));
			}
		}
		return offices;
	}

	private  Office getChildOfTree(Office officeItem,  List<Office> officeList, String extId, String type, Long grade, Boolean isAll) {
		officeItem.setChildNodes(Lists.newArrayList());
		if("2".equals(type) && officeItem.getType().equals("1")){
			officeItem.setDisabled(true);
		}
		for (Office child : officeList) {
			if ((StringUtils.isBlank(extId) || (extId!=null && !extId.equals(child.getId()) && child.getParentIds().indexOf(","+extId+",")==-1))
					&& (type == null || (type != null && (type.equals("1") ? type.equals(child.getType()) : true)))
					&& (grade == null || (grade != null && Integer.parseInt(child.getGrade()) <= grade.intValue()))
					&& JeePlusProperites.YES.equals(child.getUseable())){
				if (child.getParentId().equals(officeItem.getId())) {
					officeItem.getChildNodes().add(getChildOfTree(child, officeList, extId, type, grade, isAll));

				}
			}
		}
		return officeItem;
	}
}
