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

import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.scheduling.annotation.Async;
import org.springframework.util.ObjectUtils;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
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.ReginParams;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.patrol.business.constants.XJConstant;
import com.yeejoin.amos.patrol.business.param.RoutePageParam;
import com.yeejoin.amos.patrol.business.service.intfc.IRouteService;
import com.yeejoin.amos.patrol.business.util.CommonResponse;
import com.yeejoin.amos.patrol.business.util.CommonResponseUtil;
import com.yeejoin.amos.patrol.business.util.RoutePageParamUtil;
import com.yeejoin.amos.patrol.core.async.AsyncTask;
import com.yeejoin.amos.patrol.core.common.request.CommonPageable;
import com.yeejoin.amos.patrol.core.common.request.CommonRequest;
import com.yeejoin.amos.patrol.core.common.request.RoutePointInputItemRequest;
import com.yeejoin.amos.patrol.core.common.response.RoutePointRespone;
import com.yeejoin.amos.patrol.core.framework.Permission;
import com.yeejoin.amos.patrol.dao.entity.InputItem;
import com.yeejoin.amos.patrol.dao.entity.Plan;
import com.yeejoin.amos.patrol.dao.entity.Route;
import com.yeejoin.amos.patrol.dao.entity.RoutePoint;
import com.yeejoin.amos.patrol.feign.RemoteSecurityService;

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

@RestController
@RequestMapping(value = "/api/route")
@Api(tags="巡检路线api")
public class RouteController extends AbstractBaseController {

	private final Logger log = LoggerFactory.getLogger(RouteController.class);

	@Autowired
	private IRouteService routeService;
	
	@Autowired
	private AsyncTask asyncTask;
	@Autowired
	private RemoteSecurityService remoteSecurityService;
	/**
	 * 增加巡检路线
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "新增巡检路线", notes = "新增巡检路线")
	@PostMapping(value = "/addRoute", produces = "application/json;charset=UTF-8")
	public CommonResponse addRoute(@ApiParam(value = "巡检路线", required = true) @RequestBody Route route) {
		try {
			 ReginParams reginParams = getSelectedOrgInfo();
	            String loginOrgCode = getLoginOrgCode(reginParams);
			route.setOrgCode(loginOrgCode);
			route.setIsDelete(false);
			if (routeService.existRouteName(loginOrgCode, route.getName())) {
				return CommonResponseUtil.failure("巡检路线名称重复");
			}
			
			
			
			route.setCreatorId(getUserId());
			Route newRoute = routeService.addRoute(route);
			List<Long> routeIds = new ArrayList<>();
			routeIds.add(newRoute.getId());
			//asyncTask.pushRouteTo3D(routeIds);
			pushRouteTo3D(getToken(), getProduct(), getAppKey(),routeIds);
			return CommonResponseUtil.success();
		} catch (Exception e) {
			e.printStackTrace();
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检路线新增失败");
		}
	}

	
	


	@Async
    public void pushRouteTo3D(String toke,String product,String appKey,List<Long> ids ){
    	
    	 try {
			asyncTask.pushRouteTo3D( toke, product, appKey,ids);
			
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
        
    }
	/**
	 * 更新巡检路线
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "更新巡检路线", notes = "更新巡检路线")
	@PutMapping(value = "/updateRoute", produces = "application/json;charset=UTF-8")
	public CommonResponse updateRoute(@ApiParam(value = "巡检路线", required = true) @RequestBody Route route) {
		try {
			 ReginParams reginParams = getSelectedOrgInfo();
	            String orgCode = getLoginOrgCode(reginParams);
			route.setOrgCode(orgCode);
			route.setCreatorId(getUserId());
			Route newRoute = routeService.updateRoute(route);
			List<Long> routeIds = new ArrayList<>();
			routeIds.add(newRoute.getId());
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检路线更新失败");
		}
	}

	/**
	 * 删除巡检路线
	 * 
	 * @param routeIds
	 * @return
	 */
	@Permission
	@ApiOperation(value = "删除巡检路线", notes = "删除巡检路线")
	@DeleteMapping(value = "/deleteRoute", produces = "application/json;charset=UTF-8")
	public CommonResponse deleteRoute(@ApiParam(value = "巡检路线ID", required = false) @RequestParam List<Long> routeIds) {
		try {
			//校验1：线路上有点时返回删除失败
			Map<Long, String> idNameMap = new HashMap<>();
			for (long id : routeIds) {
				int routePointCount = routeService.countRoutePoint(id);
				if (routePointCount > 0) {
					Route route = routeService.queryRouteById(id);
					idNameMap.put(id, route.getName());
				}
			}
			if (idNameMap.size() > 0) {
				return CommonResponseUtil.failure(idNameMap, "删除路线失败：路线上已设置巡检点");
			}
			//校验2：计划在使用，删除失败
			idNameMap.clear();
			for (long id : routeIds) {
				int routePointCount = routeService.countRoutePoint(id);
				if (routePointCount > 0) {
					List<Plan> planList = routeService.queryPlanByRouteId(id);
					if(planList != null && planList.size() >0){
						idNameMap.put(id, planList.get(0).getName());
					}
				}
			}
			if (idNameMap.size() > 0) {
				return CommonResponseUtil.failure(idNameMap, "删除路线失败：计划在使用");
			}
			
			routeService.delRouteById(routeIds.toArray(new Long[0]));
			
			//asyncTask.pushRouteTo3D(routeIds);
			pushRouteTo3D(getToken(), getProduct(), getAppKey(),routeIds);
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("删除巡检路线失败");
		}
	}

	/**
	 * 根据ID查询巡检路线信息
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "查询巡检路线信息", notes = "查询巡检路线信息")
	@GetMapping(value = "/queryRouteById/{id}", produces = "application/json;charset=UTF-8")
	public CommonResponse queryRouteById(
			@ApiParam(value = "巡检路线id", required = true) @PathVariable(name = "id") long id) {
		try {
			Route route = routeService.queryRouteById(id);
			return CommonResponseUtil.success(route);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("查询巡检路线失败");
		}
	}

	@Permission
	@ApiOperation(value = "迁移路线上点到其他路线", notes = "迁移路线上点到其他路线")
	@PostMapping(value = "/migrateRoutePoint", produces = "application/json;charset=UTF-8")
	public CommonResponse migrateRoutePoint(
			@ApiParam(value = "当前巡检路线id", required = true) @RequestParam(name = "sourceRouteId") Long sourceRouteId,
			@ApiParam(value = "巡检点id", required = true) @RequestParam(name = "pointIds") List<Long> pointIds,
			@ApiParam(value = "迁移目标巡检路线id", required = true) @RequestParam(name = "targetRouteId") Long targetRouteId) {
		try {
			routeService.migrateRoutePoint(sourceRouteId, pointIds.toArray(new Long[0]), targetRouteId);
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检点迁移失败");
		}
	}

	/**
	 * 查询巡检路线信息
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "查询巡检路线信息", notes = "查询巡检路线信息")
	@PostMapping(value = "/list", produces = "application/json;charset=UTF-8")
	public CommonResponse listRoute(
			@ApiParam(value = "查询条件", required = false) @RequestBody(required = false) List<CommonRequest> queryRequests,
			@ApiParam(value = "分页参数", required = true, defaultValue = "pageNumber=0&pageSize=10") CommonPageable commonPageable) {
		try {
			ReginParams reginParams = getSelectedOrgInfo();
            String loginOrgCode = getLoginOrgCode(reginParams);
			HashMap<String,Object> paramMap = new HashMap<String,Object>();
			paramMap.put("orgCode",loginOrgCode);
			RoutePageParam params = RoutePageParamUtil.fillRouteInfoParam(queryRequests, commonPageable, paramMap);
			Page<HashMap<String, Object>> routeList = routeService.getRouteInfo(getToken(),getProduct(),getAppKey(),params);
        	
        	Set<Object> userIds = new HashSet();
        	Set<Object> depIds =new HashSet();
        	routeList.getContent().forEach(item ->{
                Object boss = item.get("boss");
                if( !ObjectUtils.isEmpty(boss) && !userIds.contains(boss)) {
                	userIds.add(boss);
    			}
                Object bossDeptId = item.get("dept_id");
    			if(!ObjectUtils.isEmpty(bossDeptId) && !depIds.contains(bossDeptId)){
    				depIds.add(bossDeptId);
        		}
        	});	
        	
        	Map<String,String> userRealNameMap = remoteSecurityService.getUserRealName(getToken(),getProduct(),getAppKey(), userIds);
        	Map<Long,String> depName = remoteSecurityService.getDepName(getToken(), getProduct(), getAppKey(), depIds);
        	
        	if( routeList != null  ) {
        		routeList.getContent().forEach(item ->{
        			Object boss = item.get("boss");
        			if(!ObjectUtils.isEmpty(boss) && userRealNameMap.containsKey(boss.toString())){
        				item.put("boss",userRealNameMap.get(boss.toString()));  
        			}
        			Object deptId = item.get("dept_id"); 
        			if(!ObjectUtils.isEmpty(deptId) && depName.containsKey(Long.valueOf(deptId.toString()))){
        				item.put("deptName",depName.get(Long.valueOf(deptId.toString())));  
        			}
        		});       		
        	}
			return CommonResponseUtil.success(routeList);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("查询巡检路线信息失败");
		}
	}
	
	@Permission
	@ApiOperation(value = "查询当前登录公司的的所有巡检路线", notes = "查询当前登录公司的的所有巡检路线")
	@GetMapping(value = "/All", produces = "application/json;charset=UTF-8")
	public CommonResponse queryAllRoute() {
		try {
			//1.组织数据权限信息
//			List<DaoCriteria> criterias = new ArrayList<DaoCriteria>();
			 //1.组织数据权限信息
            ReginParams reginParams = getSelectedOrgInfo();
            String orgCode = getLoginOrgCode(reginParams);
//			DaoCriteria compDaoCriteria = new DaoCriteria();
//			compDaoCriteria.setPropertyName("orgCode");
//			compDaoCriteria.setOperator(QueryOperatorEnum.LIKE.getName());
//			compDaoCriteria.setValue(orgCode);
//			criterias.add(compDaoCriteria);
			//2.查询
			List<Route> routeList = routeService.queryRouteList(orgCode);
			return CommonResponseUtil.success(routeList);	
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("查询巡检路线信息失败");
		}
	}
	
	@Permission
	@ApiOperation(value = "查询所有路线列表<font color='blue'>手机app</font>", notes = "查询所有路线列表<font color='blue'>手机app</font>")
	@GetMapping(value = "/routeList", produces = "application/json;charset=UTF-8")
	public CommonResponse queryRouteList() {
		try {
			AgencyUserModel userModel = getUserInfo();
            String userId = "";
            ReginParams reginParams = getSelectedOrgInfo();
            String loginOrgCode = "";
            String departmentId = "";
            String roleTypeName = getRoleTypeName(reginParams);

			if(XJConstant.ROLE_NAME_SUPERADMIN.equals(roleTypeName.toUpperCase()) || XJConstant.ROLE_NAME_ADMIN.equals(roleTypeName.toUpperCase())){
				loginOrgCode = getLoginOrgCode(reginParams);
			}else if(XJConstant.ROLE_NAME_DEPTADMIN.equals(roleTypeName.toUpperCase())){
				departmentId = getDepartmentId(reginParams);
				loginOrgCode = getLoginOrgCode(reginParams);
				userId = userModel.getUserId();
			}else if(XJConstant.ROLE_NAME_PERSON.equals(roleTypeName.toUpperCase())){
				userId = userModel.getUserId();
				loginOrgCode = getLoginOrgCode(reginParams);
			}
			List<HashMap<String, Object>> routeList = routeService.queryRouteListByOrgCode(loginOrgCode,userId,departmentId);
			routeList=routeList.stream().distinct().collect(Collectors.toList());
			return CommonResponseUtil.success(routeList);
		} catch (Exception e) {
			return CommonResponseUtil.failure(e.getMessage());
		}
	}

	/**
	 * 查询巡检路线上点列表
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "查询巡检路线上点列表", notes = "查询巡检路线上点列表")
	@PostMapping(value = "/listRoutePoint", produces = "application/json;charset=UTF-8")
	public CommonResponse listRoutePoint(@ApiParam(value = "路线id", required = true) @RequestParam long routeId,
			@ApiParam(value = "查询条件", required = false) @RequestBody(required = false) List<CommonRequest> queryRequests,
			@ApiParam(value = "分页参数", required = true, defaultValue = "pageNumber=0&pageSize=10") CommonPageable commonPageable) {
		try {
			 String uid = getUserId();
	            ReginParams reginParams = getSelectedOrgInfo();
	            String orgCode = getLoginOrgCode(reginParams);
			HashMap<String, Object> reqParam = new HashMap<>();
			reqParam.put("orgCode", orgCode);
			RoutePageParamUtil.fillRouteInfo(queryRequests, reqParam);
			Page<RoutePointRespone> pointList = routeService.queryRoutePoints(routeId, reqParam, commonPageable);
			return CommonResponseUtil.success(pointList);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("查询巡检路线上点列表失败");
		}
	}
	
	@Permission
	@ApiOperation(value = "查询巡检路线上点列表", notes = "查询巡检路线上点列表")
	@PutMapping(value = "/exchangeOrderNumber", produces = "application/json;charset=UTF-8")
	public CommonResponse exchangeRoutePointOrderNumber(@ApiParam(value = "路线巡检点id", required = true) @RequestParam long src, 
			@ApiParam(value = "路线巡检点id", required = true) @RequestParam long target) {
		if (src > 0 && target > 0) {
			routeService.exchangeRoutePointOrderNumber(src, target);
		} 
		return CommonResponseUtil.success();
	}

	/**
	 * 巡检路线上增加巡检点
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "巡检路线上增加巡检点", notes = "巡检路线上增加巡检点")
	@PostMapping(value = "/addRoutePoint", produces = "application/json;charset=UTF-8")
	public CommonResponse addRoutePoint(@ApiParam(value = "路线id", required = true) @RequestParam String routeId,
			@ApiParam(value = "巡检点ids", required = true) @RequestParam List<String> pointIds) {
		
		if(pointIds == null || pointIds.size() <=0 ){
			return CommonResponseUtil.failure("巡检点不能为空，请选择");
		}
		
		try {
			 String uid = getUserId();
	            ReginParams reginParams = getSelectedOrgInfo();
	            String loginOrgCode = getLoginOrgCode(reginParams);
			List<RoutePoint> routePointList = new ArrayList<>();
			for (String pointId : pointIds) {
				RoutePoint routePoint = new RoutePoint();
				routePoint.setRouteId(Long.parseLong(routeId));
				routePoint.setPointId(Long.parseLong(pointId));
				routePoint.setOrgCode(loginOrgCode);
				routePoint.setCreatorId(uid);
				routePointList.add(routePoint);
			}
			routeService.addRoutePoint(routePointList);
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检路线上增加巡检点失败");
		}
	}

	/**
	 * 巡检路线上删除巡检点
	 * 
	 * @param point
	 * @return
	 */
	@Permission
	@ApiOperation(value = "巡检路线上删除巡检点", notes = "巡检路线上删除巡检点")
	@DeleteMapping(value = "/deleteRoutePoint", produces = "application/json;charset=UTF-8")
	public CommonResponse deleteRoutePoint(@ApiParam(value = "路线id", required = true) @RequestParam Long routeId,
			@ApiParam(value = "巡检点ids", required = true) @RequestParam List<Long> pointIds) {

		try {
			routeService.deleteRoutePoint(routeId, pointIds.toArray(new Long[0]));
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检路线上删除巡检点失败");
		}
	}

	/**
	 * 列出巡检线路点的巡检项
	 * 
	 * @return
	 */
	@Permission
	@ApiOperation(value = "列出巡检线路点的巡检项", notes = "列出巡检线路点的巡检项")
	@PostMapping(value = "/listRoutePointInputItem", produces = "application/json;charset=UTF-8")
	public CommonResponse listRoutePointInputItem(@ApiParam(value = "路线id", required = true) @RequestBody RoutePointInputItemRequest request) {
		try {
			HashMap<String, Object> routePointInputItemList = routeService.listRoutePointInputItem(request);
			return CommonResponseUtil.success(routePointInputItemList);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("列出巡检线路点的巡检项失败");
		}
	}

	/**
	 * 列出巡检线路点的分类及巡检项
	 * 
	 * @param routeId
	 * @param pointId
	 * @return
	 */
	@Permission
	@ApiOperation(value = "列出巡检线路点的分类及巡检项", notes = "列出巡检线路点的分类及巡检项")
	@PostMapping(value = "/listRoutePointInputItemWithClassify", produces = "application/json;charset=UTF-8")
	public CommonResponse listRoutePointInputItemWithClassify(@ApiParam(value = "路线id", required = true) @RequestParam long routeId,
			@ApiParam(value = "巡检点id", required = true) @RequestParam long pointId) {
		try {
			Map<String, List<InputItem>> classifiedInputItemMap = routeService.listRoutePointInputItemWithClassify(routeId, pointId);
			return CommonResponseUtil.success(classifiedInputItemMap);
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("列出巡检线路点的分类及巡检项失败");
		}
	}
	
	/**
	 * 修改巡检线路点的巡检项
	 * 
	 * @param routeId
	 * @param pointId
	 * @param inputItemIds
	 * @return
	 */
	@Permission
	@ApiOperation(value = "修改巡检线路点的巡检项", notes = "修改巡检线路点的巡检项")
	@PostMapping(value = "/updateRoutePointInputItem", produces = "application/json;charset=UTF-8")
	public CommonResponse updateRoutePointInputItem(@ApiParam(value = "巡检路线id", required = true) @RequestParam Long routeId, 
			@ApiParam(value = "巡检点id", required = true) @RequestParam Long pointId,
			@ApiParam(value = "巡检点巡检项id", required = true) @RequestParam List<Long> inputItemIds) {
		try {
			routeService.updateRoutePointInputItem(routeId, pointId, inputItemIds.toArray(new Long[0]));
			return CommonResponseUtil.success();
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("修改巡检线路点的巡检项失败");
		}
	}
	
	/**
	 * 根据巡检路线ID获取该路线上的所有点ID
	 * @return IDs
	 */
	@Permission
	@ApiOperation(value = "获取巡检路线上的所有点ID", notes = "获取巡检路线上的所有点ID")
	@RequestMapping(value = "/points/{routeID}", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public CommonResponse getPointIDByRouyeId(@ApiParam(value = "巡检路线ID") @PathVariable(required = true) Long routeID) {
		List<Long> pointIDs = routeService.getPointIDByRouyeId(routeID);
		return CommonResponseUtil.success(pointIDs);
	}
	
	/**
	 * 根据巡检路线ID获取该路线上的所有点ID
	 * @return IDs
	 */
	@Permission
	@ApiOperation(value = "获取巡检路线上的所有点ID", notes = "获取巡检路线上的所有点ID")
	@RequestMapping(value = "/points", produces = "application/json;charset=UTF-8", method = RequestMethod.POST)
	public CommonResponse getPointIDByRouteId(@ApiParam(value = "巡检路线ID信息") @RequestBody(required = true) Map routeInfo) {
		List<String> routeIdList = (List<String>) routeInfo.get("routeIDs");
		LinkedHashMap<String, Object> routePointIdMap = routeService.getPointIdByRouteId(routeIdList);
		return CommonResponseUtil.success(routePointIdMap);
	}

	/**
	 * 修改保存巡检路线
	 * @return IDs
	 */
	@Permission
	@ApiOperation(value = "新*保存巡检路线", notes = "新*保存巡检路线")
	@PutMapping(value = "/save-new", produces = "application/json;charset=UTF-8")
	public CommonResponse updateRouteNew(@ApiParam(value = "巡检路线", required = true) @RequestBody Route route) {
		try {
			ReginParams reginParams = getSelectedOrgInfo();
			String orgCode = getLoginOrgCode(reginParams);
			route.setOrgCode(orgCode);
			route.setCreatorId(getUserId());
			return CommonResponseUtil.success(routeService.updateRouteNew(route));
		} catch (Exception e) {
			log.error(e.getMessage(), e);
			return CommonResponseUtil.failure("巡检路线更新失败");
		}
	}

}
