package com.yeejoin.amos.patrol.business.controller;

import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.yeejoin.amos.boot.biz.common.bo.DepartmentBo;
import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.feign.privilege.model.CompanyModel;
import com.yeejoin.amos.feign.privilege.model.DepartmentModel;
import com.yeejoin.amos.patrol.business.service.intfc.ISafety3DDataSendService;
import com.yeejoin.amos.patrol.business.util.CommonResponse;
import com.yeejoin.amos.patrol.business.util.CommonResponseUtil;
import com.yeejoin.amos.patrol.core.common.response.TaskInfoRespone;
import com.yeejoin.amos.patrol.core.framework.Permission;
import com.yeejoin.amos.patrol.email.IEmailService;
import com.yeejoin.amos.patrol.feign.RemoteSecurityService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * 获取部门、公司信息
 * @author gaodongdong
 *
 */
@RestController
@RequestMapping(value = "/api/group")
@Api(tags="公司，部门数据api")
public class GroupController extends AbstractBaseController{
	private final Logger log = LoggerFactory.getLogger(GroupController.class);
	
	@Autowired
	private RemoteSecurityService remoteSecurityService;
	@Autowired
	IEmailService emailService;

	/**
	 * 部门查询
	 * @return
	 */
	@Permission
	@ApiOperation(value = "获取当前用户所属公司的所有部门", notes = "获取当前用户所属公司的所有部门")
	@RequestMapping(value = "/queryDept", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse queryCurrentCompanyDept() {
		/*String loginOrgCode = getLoginUserParam().getLoginOrgCode();
		String[] orgs = loginOrgCode.split("\\*");
		List<SDepartment> list = groupService.findByCompanyId(Long.parseLong(orgs[orgs.length - 1]));
		List<LinkedHashMap<String, Object>> res = new ArrayList<>();
		for (SDepartment d : list) {
			LinkedHashMap<String, Object> dept = new LinkedHashMap<>();
			dept.put("id", d.getId());
			dept.put("key", d.getId());
			dept.put("value", d.getId());
			dept.put("state", "open");
			dept.put("type", "department");
			dept.put("orgCode", loginOrgCode+"-"+d.getDepmCode());
			dept.put("label", d.getDepartmentName());
			dept.put("title", d.getDepartmentName());
			dept.put("name", d.getDepartmentName());
			dept.put("writeable", 0);
			res.add(dept);
		}
		LinkedHashMap<String, Object> dept = new LinkedHashMap<>();
		dept.put("id", -1);
		dept.put("key", -1);
		dept.put("value", -1);
		dept.put("state", "close");
		dept.put("type", "department");
		dept.put("label", "其他");
		dept.put("title", "其他");
		dept.put("name", "其他");
		dept.put("writeable", 0);
		res.add(dept);*/
		List<LinkedHashMap<String, Object>> res = new ArrayList<>();
		ReginParams reginParams = getSelectedOrgInfo();
		String dep = reginParams.getCompany().getSequenceNbr().toString();
		List<DepartmentModel> departmentModels = remoteSecurityService.listDepartmentsByCompanyId(getToken(), getProduct(), getAppKey(), dep);

		List<DepartmentBo> departmentBos = ModelToBo(departmentModels);

		String loginOrgCode = reginParams.getCompany().getOrgCode();

		for (DepartmentBo d : departmentBos) {
			LinkedHashMap<String, Object> dept = new LinkedHashMap<>();
			dept.put("id", d.getSequenceNbr());
			dept.put("key", d.getSequenceNbr());
			dept.put("value", d.getSequenceNbr());
			dept.put("state", "open");
			dept.put("type", "department");
			dept.put("orgCode", loginOrgCode+"-"+d.getSequenceNbr());
			dept.put("label", d.getDepartmentName());
			dept.put("title", d.getDepartmentName());
			dept.put("name", d.getDepartmentName());
			dept.put("writeable", 0);
			res.add(dept);
		}


		//查询没有部门的人员信息
		CompanyModel companyModel = remoteSecurityService.listUserByCompanyId1(getToken(), getProduct(), getAppKey(), dep);

		List children = (List) companyModel.getChildren();


		for (int i = 0; i < children.size(); i++) {
			Map<String, Object> map = (LinkedHashMap) children.get(i);
			if("其他".equals((map.get("departmentName").toString()))){
				LinkedHashMap<String, Object> dept = new LinkedHashMap<>();
				dept.put("id", "-1");
				dept.put("key", "-1");
				dept.put("value", "-1");
				dept.put("state", "close");
				dept.put("type", "department");
				dept.put("label", "其他");
				dept.put("title", "其他");
				dept.put("name", "其他");
				dept.put("writeable", "0");
				res.add(dept);
			}


		}

		//return CommonResponseUtil.success(departmentBos);
		return CommonResponseUtil.success(res);
	}

	@Permission
	@ApiOperation(value = "获取当前用户所属公司的所有部门及人员", notes = "获取当前用户所属公司的所有部门及人员")
	@RequestMapping(value = "/queryDeptAndUser",produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse queryCurrentCompanyDeptAndUser() {
		List<LinkedHashMap<String, Object>> res = new ArrayList<>();

		ReginParams reginParams = getSelectedOrgInfo();
		String companyId = reginParams.getCompany().getSequenceNbr().toString();

		// 获取部门及人员信息
		res = getDeptAndUser(companyId);

		return CommonResponseUtil.success(res);
	}

	/**
	 * 根据公司id获取部门及人员信息
	 * @param companyId
	 * @return
	 */
	private List<LinkedHashMap<String, Object>> getDeptAndUser( String companyId){

		List<LinkedHashMap<String, Object>> res = new ArrayList<>();
		CompanyModel companyModel = remoteSecurityService.listUserByCompanyId1(getToken(), getProduct(), getAppKey(), companyId);
		String loginOrgCode = String.valueOf(companyModel.getCompanyOrgCode());
		List children = (List) companyModel.getChildren();

		for (int i = 0; i < children.size(); i++) {
			Map<String, Object> map = (LinkedHashMap) children.get(i);
			LinkedHashMap<String, Object> dept = new LinkedHashMap<>();
			if("其他".equals((map.get("departmentName").toString()))){
				dept.put("id", "-1");
				dept.put("key", "-1");
				dept.put("value", "-1");
				dept.put("state", "close");
				dept.put("label", "其他");
				dept.put("title", "其他");
				dept.put("name", "其他");
				List userModelList = (List) map.get("userModelList");
				dept.put("children", getUserModelList(userModelList, "-1"));
			}else{
				dept.put("id", map.get("sequenceNbr"));
				dept.put("key", map.get("sequenceNbr"));
				dept.put("value", map.get("sequenceNbr"));
				dept.put("state", "open");
				dept.put("orgCode", loginOrgCode+"-"+map.get("sequenceNbr"));
				dept.put("label", map.get("departmentName"));
				dept.put("title", map.get("departmentName"));
				dept.put("name", map.get("departmentName"));
				//人员集合
				List userModelList = (List) map.get("userModelList");
				dept.put("children", getUserModelList(userModelList, map.get("sequenceNbr")));
			}
			dept.put("type", "department");
			dept.put("writeable", 0);
			res.add(dept);
		}
		return res;
	}

	/**
	 * 部门人员转换
	 * @param userModelList
	 * @return
	 */
	private List getUserModelList(List userModelList, Object deptId){

		List<LinkedHashMap<String, Object>> res = new ArrayList<>();
		for(int i = 0; i < userModelList.size(); i++){
			Map<String, Object> map = (LinkedHashMap) userModelList.get(i);
			LinkedHashMap<String, Object> user = new LinkedHashMap<>();

			user.put("id", map.get("sequenceNbr"));
			if("-1".equals(deptId)){
//				user.put("id", map.get("userId").toString() + "@" + "-1");
				user.put("key", map.get("sequenceNbr") + "-1");
				user.put("value", map.get("userId").toString() + "@" + "-1");
			}else{
//				user.put("id", map.get("userId").toString() + "@" + deptId.toString());
				user.put("key", map.get("sequenceNbr") + deptId.toString());
				user.put("value", map.get("userId").toString() + "@" + deptId.toString());
			}
			user.put("label", map.get("realName"));
			user.put("title", map.get("realName"));
			user.put("name", map.get("realName"));
			user.put("userId", map.get("userId"));
			res.add(user);
		}

		return res;
	}

	/**
	 * 类型转换  DepartmentModel => DepartmentBo
	 * @param departmentModels
	 * @return
	 */
	private List<DepartmentBo> ModelToBo(List<DepartmentModel> departmentModels){
		List<DepartmentBo> departmentBos = new ArrayList<>();
		departmentModels.forEach(
				x -> {
					DepartmentBo departmentBo = new DepartmentBo();
					departmentBo.setSequenceNbr(x.getSequenceNbr());
					departmentBo.setCompanySeq(x.getCompanySeq());
					departmentBo.setDepartmentDesc(x.getDepartmentDesc());
					departmentBo.setDepartmentName(x.getDepartmentName());
					departmentBo.setDeptOrgCode(x.getDeptOrgCode());
					departmentBo.setLevel(x.getLevel());
					departmentBo.setOrgCode(x.getOrgCode());
					departmentBo.setParentId(x.getParentId());
					if (!ObjectUtils.isEmpty(x.getChildren())) {
						Object collect = x.getChildren().stream().collect(Collectors.toList());
						List<LinkedHashMap> children = (List<LinkedHashMap>) collect;
						//departmentBo.setChildren(children);
						departmentBos.addAll(ModelToBo2(children));
					}
					departmentBos.add(departmentBo);
				}
		);
		return departmentBos;
	}
	private List<DepartmentBo> ModelToBo2(List<LinkedHashMap> departmentModels){
		List<DepartmentBo> departmentBos = new ArrayList<>();
		departmentModels.forEach(
				x -> {
					DepartmentBo departmentBo = new DepartmentBo();
					departmentBo.setSequenceNbr(Long.valueOf(x.get("sequenceNbr").toString()));
					departmentBo.setCompanySeq(Long.valueOf(x.get("companySeq").toString()));
					departmentBo.setDepartmentDesc(x.get("departmentDesc")+"");
					departmentBo.setDepartmentName(x.get("departmentName")+"");
					departmentBo.setDeptOrgCode(Integer.valueOf(x.get("deptOrgCode")+""));
					departmentBo.setLevel(x.get("level")+"");
					departmentBo.setOrgCode(x.get("orgCode")+"");
					departmentBo.setParentId(Long.valueOf(x.get("parentId").toString()));

					if (x.get("children")!=null) {
						List<LinkedHashMap> collect = (List<LinkedHashMap>) x.get("children");
						departmentBos.addAll( ModelToBo2(collect));
					}
					departmentBos.add(departmentBo);
				}
		);
		return departmentBos;
	}

	/**
	 * 部获取指定公司ID的所有末端公司信息
	 * @param companyId
	 * @return
	 */
	@Permission
	@ApiOperation(value = "根据指定公司ID获取公司和所属公司的子公司信息", notes = "根据指定公司ID获取公司和所属公司的子公司信息")
	@RequestMapping(value = "/queryCompanyLeaves", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse queryCompanyLeavesById(@ApiParam(value="公司Id") @RequestParam("companyId") String companyId) {
		try {
			if (ObjectUtils.isEmpty(companyId)) {
				return CommonResponseUtil.failure("companyId is empty!!!");
			}
			List<CompanyModel> amosRes = remoteSecurityService.getCompanyTreeByCompanyId(getToken(), getProduct(), getAppKey(),companyId);
			//List response = getLeaves((List<LinkedHashMap<String, Object>>) amosRes.getDataList());
			return CommonResponseUtil.success(amosRes);
		}catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	/**
	 * 根据用户所有属公司ID，查询所有子公司末端公司信息
	 * @return
	 */
	@Permission
	@ApiOperation(value = "获取用户所属公司和所属公司的子公司信息", notes = "获取用户所属公司和所属公司的子公司信息")
	@RequestMapping(value = "/queryAuthCompanyLeaves", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse queryAuthCompanyLeaves() {
		try {
			//User user = getUserInfo();
			//Long companyId = user.getCompany().getId();

			ReginParams reginParams = getSelectedOrgInfo();
			String companyId= reginParams.getCompany().getSequenceNbr().toString();
			//CommonResponse amosRes = amosSecurityServer.queryCompanyLeavesById(companyId + "");
			List<CompanyModel> amosRes = remoteSecurityService.getCompanyTreeByCompanyId(getToken(), getProduct(), getAppKey(),companyId);

			//List response = getLeaves((List<LinkedHashMap<String, Object>>) amosRes.getDataList());
			return CommonResponseUtil.success(amosRes);
		}catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	/**
	 * 递归调用获取list中的末端节点
	 * @param src
	 * @return
	 */
	private List<LinkedHashMap<String, Object>> getLeaves(List<LinkedHashMap<String, Object>> src) {
		List<LinkedHashMap<String, Object>> dest = new ArrayList<>();
		for (LinkedHashMap<String, Object> leaves : src) {
			if (ObjectUtils.isEmpty(leaves.get("children"))) {
				dest.add(leaves);
			} else {
				List<LinkedHashMap<String, Object>> list = getLeaves((List<LinkedHashMap<String, Object>>) leaves.get("children"));
				dest.addAll(list);
			}

		}
		return dest;
	}


	@Autowired
	private ISafety3DDataSendService safety3DDataSend;
	//@Authorization(ingore=true)
	@Permission
	@ApiOperation(value = "检查点状态推送", notes = "检查点状态推送")
	@RequestMapping(value = "/testCheckPushStatus", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse testCheckPushStatus(@ApiParam(value="Id") @RequestParam("checkId") long checkId) {
		try {
//			asyncTask.pushCheckInfoTo3D(checkId);
//			messageService.pushCheckMessage(checkId);
			return CommonResponseUtil.success();
		}catch (Exception e) {
			log.error(e.getMessage());;
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	//@Authorization(ingore=true)
	@Permission
	@ApiOperation(value = "任务状态推送", notes = "任务状态推送")
	@RequestMapping(value = "/testTaskPushStatus", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse testTaskPushStatus(@ApiParam(value="Id") @RequestParam("checkId") Long taskId) {
		try {
			TaskInfoRespone taskInfoRespone = safety3DDataSend.taskDetailInfoPush(getToken(), getProduct(), getAppKey(),taskId);
			return CommonResponseUtil.success(taskInfoRespone);
		}catch (Exception e) {
			log.error(e.getMessage());;
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	@Permission
	@ApiOperation(value = "巡检点信息", notes = "巡检点信息")
	@RequestMapping(value = "/pointInfo", produces = "application/json;charset=UTF-8", method = RequestMethod.GET)
	public CommonResponse getPointInfo(@ApiParam(value="Id") @RequestParam("pointId") Long pointId) {
		try {
			List<Long> ids = new ArrayList<>();
			ids.add(pointId);
			return CommonResponseUtil.success(safety3DDataSend.pushPointTo3D(getToken(), getProduct(), getAppKey(),ids));
		}catch (Exception e) {
			log.error(e.getMessage());;
			return CommonResponseUtil.failure(e.getMessage());
		}
	}
}
