package xiaoqu.home.open.controller;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import xiaoqu.home.open.aop.AvoidRepeatSubmit;
import xiaoqu.home.open.controller.export.TaskInfoExport;
import xiaoqu.home.open.controller.input.plan.PlanTaskOrderInsert;
import xiaoqu.home.open.controller.input.task.GridAndSceneInput;
import xiaoqu.home.open.controller.input.task.TaskInfoPageInput;
import xiaoqu.home.open.controller.input.task.TaskTaskOrderInsert;
import xiaoqu.home.open.model.db1.User;
import xiaoqu.home.open.model.db2.*;
import xiaoqu.home.open.publicBean.BaseOutput;
import xiaoqu.home.open.publicBean.IdEntity;
import xiaoqu.home.open.publicBean.MessageNotification;
import xiaoqu.home.open.publicBean.PageOutput;
import xiaoqu.home.open.publicBean.task.TaskCancel;
import xiaoqu.home.open.publicBean.task.TaskInfoDetailOutput;
import xiaoqu.home.open.publicBean.task.TaskInfoOutput;
import xiaoqu.home.open.publicBean.task.TaskObject;
import xiaoqu.home.open.publicBean.task.TaskOperation;
import xiaoqu.home.open.publicBean.task.TaskPoint;
import xiaoqu.home.open.publicBean.task.TaskProgress;
import xiaoqu.home.open.service.RedisService4;
import xiaoqu.home.open.service.db1.UserService;
import xiaoqu.home.open.service.db2.FieldWebpageAuthorityService;
import xiaoqu.home.open.service.db2.OperationService;
import xiaoqu.home.open.service.db2.PlanObjectService;
import xiaoqu.home.open.service.db2.PlanOperationService;
import xiaoqu.home.open.service.db2.TaskInfoService;
import xiaoqu.home.open.service.db2.TaskScenesService;
import xiaoqu.home.open.service.db2.TaskStatusLogService;
import xiaoqu.home.open.service.db2.TaskUserService;
import xiaoqu.home.open.service.db2.TypeSourceService;
import xiaoqu.home.open.service.db2.WageService;
import xiaoqu.home.open.utils.ResultResponseBeanUtil;
import xiaoqu.home.open.utils.StringUtil;
import xiaoqu.home.open.utils.UserUtils;
import xiaoqu.home.open.utils.WrapperUtils;
import xiaoqu.home.open.utils.poi.ExcelUtil;

@RestController
@RequestMapping(value = "/task")
@Api(value = "任务查询", description = "任务查询")
public class TaskController {
	@Autowired
	private TaskInfoService taskInfoService;
	@Autowired
	private TaskUserService taskUserService;
	@Autowired
	private TaskScenesService taskScenesService;
	@Autowired
	private PlanObjectService planObjectService;
	@Autowired
	private PlanOperationService planOperationService;
	@Autowired
	private TypeSourceService typeSourceService;
	@Autowired
	private OperationService operationService;
	@Autowired
	private TaskStatusLogService taskStatusLogService;
	@Autowired
	private FieldWebpageAuthorityService fieldWebpageAuthorityService;

	@Autowired
	WageService wageService;

	@ApiOperation(value = "分页查询")
	@RequestMapping(value = "/pageList", method = RequestMethod.POST)
	public BaseOutput<PageOutput<TaskInfoOutput>> pageList(HttpServletRequest request, @RequestBody TaskInfoPageInput input) {
		PageOutput<TaskInfoOutput> output = new PageOutput<TaskInfoOutput>();
		Long districtId = input.getDistrictId();
		if (StringUtil.isNull(districtId)) {
			return ResultResponseBeanUtil.fail("请选择站点");
		}
		QueryWrapper<TaskInfo> wrapper = WrapperUtils.getWrapper(false);
		wrapper.ge("status", 2);// 条件限定
		if (input.getTaskType() == null) {
			wrapper.in("task_type", 0, 1, 2);
		}
		if (StringUtil.isNotEmpty(input.getGridAndScenes())) {
			Set<Long> taskIds = GetQueryCiteria(input);
			if (taskIds.size() == 0) {
				return ResultResponseBeanUtil.success(output);
			} else {
				wrapper.in("id", taskIds);
			}
			input.setGridAndScenes(null);
		}
		wrapper = WrapperUtils.beanToWrapper(wrapper, input);

//		User user = UserUtils.getUser(request);
//		List<FieldWebpageAuthority> fieldList = fieldWebpageAuthorityService.getFieldList(input.getWebId(), user.getPropertyAuthorityId());
//		String[] columns = WrapperUtils.entityToColumns(fieldList);
//		wrapper.select(columns);

		Page<TaskInfo> pageList = new Page<TaskInfo>(input.getPage(), input.getRows());
		List<TaskInfo> entityList = taskInfoService.page(pageList, wrapper).getRecords();
		List<TaskInfoOutput> outList = new ArrayList<TaskInfoOutput>();
		if (entityList.size() > 0) {
			Map<Long, String> wageToName = new HashMap<Long, String>();
			QueryWrapper<Wage> wagWrapper = WrapperUtils.getWrapper(false);
			wagWrapper.eq("district_id", input.getDistrictId());
			List<Wage> wages = wageService.list(wagWrapper);
			if (wages.size() > 0) {
				for (Wage wage : wages) {
					wageToName.put(wage.getId(), wage.getName());
				}
			}
			for (TaskInfo bean : entityList) {
				TaskInfoOutput outputBean = new TaskInfoOutput();
				BeanUtils.copyProperties(bean, outputBean);
				outList.add(outputBean);
			}
		}
		output.setPage(pageList.getCurrent());
		output.setRecords(pageList.getTotal());
		output.setTotal(pageList.getPages());
		output.setRows(outList);
		return ResultResponseBeanUtil.success(output);
	}

	/********
	 * 查询列表和导出统一处理查询条件
	 * 
	 * @param input
	 * @return
	 */
	private Set<Long> GetQueryCiteria(TaskInfoPageInput input) {
		Set<Long> taskIds = new HashSet<Long>();
		List<GridAndSceneInput> gridAndScenes = input.getGridAndScenes();
		for (GridAndSceneInput gridAndSceneInput : gridAndScenes) {
			QueryWrapper<TaskScenes> wrapperTaskScenes = WrapperUtils.getWrapper(false);
			wrapperTaskScenes.eq("district_id", input.getDistrictId());
//				@ApiModelProperty("网格或场景级别")
			Integer level = gridAndSceneInput.getLevel();
//				@ApiModelProperty(value = "网格ID")
			Long gridId = gridAndSceneInput.getGridId();
//				@ApiModelProperty(value = "场景ID")
			Long sceneId = gridAndSceneInput.getSceneId();
//				@ApiModelProperty(value = "是否场景，0:否;1:是")
			Integer isscene = gridAndSceneInput.getIsscene();
			if (isscene == 0) {
//				    @TableField("building_id")
//				    @TableField("floor_id")
//				    @TableField("multistage_grid_id")
				switch (level) {
				case 1:
					wrapperTaskScenes.eq("building_id", gridId);
					break;
				case 2:
					wrapperTaskScenes.eq("floor_id", gridId);
					break;
				default:
					wrapperTaskScenes.eq("multistage_grid_id", gridId);
					break;
				}
				wrapperTaskScenes.eq("grid_level", level);
			} else {
				switch (level) {
				case 1:
					wrapperTaskScenes.eq("scenes_id", sceneId);
					break;
				case 2:
					wrapperTaskScenes.eq("scenes_id", sceneId);
					break;
				}
				wrapperTaskScenes.eq("scenes_level", level);
			}
//			@ApiModelProperty(value = "任务生成时间")
//			private String createTimeStart;
			if (StringUtil.isNotEmpty(input.getCreateTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getCreateTimeStart());
				wrapperTaskScenes.le("create_time", input.getCreateTimeEnd());
			}
//				@ApiModelProperty(value = "任务派发时间")
//				private String sendTimeStart;
			if (StringUtil.isNotEmpty(input.getSendTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getSendTimeStart());
				wrapperTaskScenes.le("create_time", input.getSendTimeEnd());
			}
//				@ApiModelProperty(value = "任务响应时间")
//				private String confirmTimeStart;
			if (StringUtil.isNotEmpty(input.getConfirmTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getConfirmTimeStart());
				wrapperTaskScenes.le("create_time", input.getConfirmTimeEnd());
			}
//				@ApiModelProperty(value = "任务作业时间")
//				private String actionTimeStart;
			if (StringUtil.isNotEmpty(input.getActionTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getActionTimeStart());
				wrapperTaskScenes.le("create_time", input.getActionTimeEnd());
			}
//				@ApiModelProperty(value = "任务完成时间")
//				private String finishTimeStart;
			if (StringUtil.isNotEmpty(input.getFinishTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getFinishTimeStart());
				wrapperTaskScenes.le("create_time", input.getFinishTimeEnd());
			}
//				@ApiModelProperty(value = "任务过期时间")
//				private String expireTimeStart;
			if (StringUtil.isNotEmpty(input.getExpireTimeStart())) {
				wrapperTaskScenes.ge("create_time", input.getExpireTimeStart());
				wrapperTaskScenes.le("create_time", input.getExpireTimeEnd());
			}
			List<TaskScenes> taskScenes = taskScenesService.list(wrapperTaskScenes);
			taskIds.addAll(taskScenes.stream().map(taskScen -> taskScen.getTaskId()).collect(Collectors.toSet()));
		}
		return taskIds;
	}

	@ApiOperation(value = "任务导出")
	@PostMapping("/export")
	public void export(HttpServletRequest request, HttpServletResponse response, @RequestBody TaskInfoPageInput input) throws IOException {
		if (StringUtil.isNull(input.getDistrictId())) {
			return;
		}
		List<TaskInfoExport> outList = new ArrayList<TaskInfoExport>();
		User user = UserUtils.getUser(request);
		QueryWrapper<TaskInfo> wrapper = WrapperUtils.getWrapper(false);
		wrapper.ge("status", 2);// 限定查询条件
		if (input.getTaskType() == null) {
			wrapper.in("task_type", 0, 1, 2);
		}
		if (StringUtil.isNotEmpty(input.getGridAndScenes())) {
			Set<Long> taskIds = GetQueryCiteria(input);
			if (taskIds.size() == 0) {
				return;
			} else {
				wrapper.in("id", taskIds);
			}
			input.setGridAndScenes(null);
		}
		wrapper = WrapperUtils.beanToWrapper(wrapper, input);
		List<TaskInfo> taskInfoList = taskInfoService.list(wrapper);

		for (TaskInfo taskInfo : taskInfoList) {
			TaskInfoExport taskInfoExport = new TaskInfoExport();
			BeanUtils.copyProperties(taskInfo, taskInfoExport);
			outList.add(taskInfoExport);
		}

		List<FieldWebpageAuthority> fieldList = fieldWebpageAuthorityService.getExportFieldList(input.getWebId(), user.getPropertyAuthorityId());
		String[] exportColumns = WrapperUtils.entityToColumns(fieldList);
		ExcelUtil<TaskInfoExport> util = new ExcelUtil<TaskInfoExport>(TaskInfoExport.class);
		util.exportExcelByColumns(response, outList, "任务明细", exportColumns);
	}

	@Autowired
	private RedisService4 redisService4;
	@Autowired
	private RedisTemplate<String, String> redisTemplate5;

	@ApiOperation(value = "取消任务")
	@RequestMapping(value = "/cancel", method = RequestMethod.POST)
	public BaseOutput<String> cancel(HttpServletRequest request, @RequestBody TaskCancel input) {
		User user = UserUtils.getUser(request);
		if (StringUtil.isNull(input.getId())) {
			return ResultResponseBeanUtil.fail("请输入任务ID");
		}
		TaskInfo taskInfo = taskInfoService.getById(input.getId());
		if (StringUtil.isNull(taskInfo)) {
			return ResultResponseBeanUtil.fail("任务不存在");
		}
//		待抢单 已接单 作业中
//		任务状态(0:已生成;1:已匹配;2:待抢单;3:已接单;4:作业中;5:按时完成;6:超时完成;7:人工取消;8:系统取消;9:未完成)")
		if (taskInfo.getStatus() == 2 || taskInfo.getStatus() == 3 || taskInfo.getStatus() == 4) {
			taskInfo.setStatus(7);
			taskInfo.setModifyTime(new Date());
			taskInfoService.updateById(taskInfo);
			TaskStatusLog taskStatusLog = new TaskStatusLog();
			BeanUtils.copyProperties(taskInfo, taskStatusLog, "id");
			taskStatusLog.setCreateTime(new Date());
			taskStatusLog.setTaskId(taskInfo.getId());
			taskStatusLog.setTaskStatus(7);
			taskStatusLog.setCancelReason(input.getCancelReason());
			taskStatusLog.setDetailReason(input.getDetailReason());
			taskStatusLog.setContent(user.getName() + " " + user.getMobile());
			taskStatusLogService.save(taskStatusLog);
			// 同时取消taskuser表的数据
			UpdateWrapper<TaskUser> taskUserWrapper = WrapperUtils.getUpdateWrapper(false);
			taskUserWrapper.eq("task_id", input.getId());
			taskUserWrapper.set("status", 7);
			taskUserWrapper.set("modify_time", new Date());
			taskUserService.update(taskUserWrapper);
			// 个推推送
			MessageNotification messageNotification = new MessageNotification();
			messageNotification.setDistrictId(taskInfo.getDistrictId());
			messageNotification.setStatus(taskInfo.getStatus());
			messageNotification.setTaskId(taskInfo.getId());
			messageNotification.setTaskName(taskInfo.getName());
			redisService4.lPush("taskPushQueue", JSON.toJSONString(messageNotification));
			/*** 通知匹配算法重新算 ***/
			redisTemplate5.opsForSet().add("RepeatTaskQueue", taskInfo.getDistrictId() + "");
			/****** 任务结束通知 ******/
			redisTemplate5.opsForList().leftPush("FinishTaskQueue", taskInfo.getId() + "");
			// 修改人员状态
			QueryWrapper<TaskUser> qWrapper = WrapperUtils.getWrapper(false);
			qWrapper.eq("task_id", input.getId());
			List<TaskUser> tempList = taskUserService.list(qWrapper);
			if (tempList.size() > 0) {
				for (TaskUser taskUser : tempList) {
					if (taskUser.getUserId() != null && taskUser.getUserId().intValue() != 0) {
						User temUser = userService.getById(taskUser.getUserId());
						if (temUser.getWorkAtStatus() != 3) {// 工作中状态0:作业;1:转场;2:空闲;3:休息
							// 查询有没有待完成的任务
							QueryWrapper<TaskUser> taskUserQuery = WrapperUtils.getWrapper(false);
							taskUserQuery.eq("status", 4);// 3:已接单;4:作业中;
							taskUserQuery.eq("user_id", temUser.getId());
							int countTemp = taskUserService.count(taskUserQuery);
							if (countTemp > 0) {
								temUser.setWorkAtStatus(0);// 工作中状态0:作业;1:转场;2:空闲;3:休息
								temUser.setModifyTime(new Date());
								userService.updateById(temUser);
							} else {
								QueryWrapper<TaskUser> taskUserQuery1 = WrapperUtils.getWrapper(false);
								taskUserQuery1.eq("status", 3);// 3:已接单;4:作业中;
								taskUserQuery1.eq("user_id", temUser.getId());
								countTemp = taskUserService.count(taskUserQuery1);
								if (countTemp > 0) {
									temUser.setWorkAtStatus(1);// 工作中状态0:作业;1:转场;2:空闲;3:休息
									temUser.setModifyTime(new Date());
									userService.updateById(temUser);
								} else {
									temUser.setWorkAtStatus(2);// 工作中状态0:作业;1:转场;2:空闲;3:休息
									temUser.setModifyTime(new Date());
									userService.updateById(temUser);
								}
							}
						}
					}

				}

			}
			return ResultResponseBeanUtil.success("取消成功");
		} else {
			return ResultResponseBeanUtil.fail("当前状态不支持此操作");
		}
	}

	@Autowired
	UserService userService;

	@ApiOperation(value = "查看任务")
	@RequestMapping(value = "/look", method = RequestMethod.POST)
	public BaseOutput<TaskInfoDetailOutput> look(HttpServletRequest request, @RequestBody IdEntity input) {
		TaskInfoDetailOutput taskInfoDetailOutput = new TaskInfoDetailOutput();
		if (StringUtil.isNull(input.getId())) {
			return ResultResponseBeanUtil.fail("请输入任务ID");
		}
		TaskInfo taskInfo = taskInfoService.getById(input.getId());
		if (StringUtil.isNull(taskInfo)) {
			return ResultResponseBeanUtil.fail("任务不存在");
		}
		BeanUtils.copyProperties(taskInfo, taskInfoDetailOutput);
		// 对象分类
		if (taskInfo.getPlanId() != 0) {
			QueryWrapper<PlanObject> planObjectWrapper = WrapperUtils.getWrapper(false);
			planObjectWrapper.eq("plan_id", taskInfo.getPlanId());
			planObjectWrapper.orderByAsc("id");
			List<PlanObject> planObjects = planObjectService.list(planObjectWrapper);
			if (StringUtil.isNotEmpty(planObjects)) {
				List<TaskObject> taskObjectS = new ArrayList<TaskObject>();
				for (PlanObject planObject : planObjects) {
					TaskObject taskObject = new TaskObject();
					BeanUtils.copyProperties(planObject, taskObject);
					taskObjectS.add(taskObject);
				}
				taskInfoDetailOutput.setTaskObjects(taskObjectS);
			}
			// 任务作业
			QueryWrapper<PlanOperation> planOperationWrapper = WrapperUtils.getWrapper(false);
			planOperationWrapper.eq("plan_id", taskInfo.getPlanId());
			planOperationWrapper.orderByAsc("id");
			List<PlanOperation> planOperations = planOperationService.list(planOperationWrapper);
			if (StringUtil.isNotEmpty(planOperations)) {
				List<TaskOperation> taskOperations = new ArrayList<TaskOperation>();
				QueryWrapper<TypeSource> queryWrapper = WrapperUtils.getWrapper(false);
				queryWrapper.eq("type_name", "operationType");
				queryWrapper.orderByAsc("order_by");
				List<TypeSource> typelist = typeSourceService.list(queryWrapper);
				Map<String, String> maps = typelist.stream().collect(Collectors.toMap(TypeSource::getName, TypeSource::getContent));

				for (PlanOperation planObject : planOperations) {
					Operation operation = operationService.getById(planObject.getOperationId());
					TaskOperation taskOperation = new TaskOperation();
					if (maps.containsKey(operation.getType().toString())) {
						taskOperation.setTypeString(maps.get(operation.getType().toString()));
					}
					taskOperation.setObjectName(operation.getObjectName());
					taskOperation.setObjectParentName(operation.getObjectParentName());
					BeanUtils.copyProperties(planObject, taskOperation);
					taskOperations.add(taskOperation);
				}
				taskInfoDetailOutput.setTaskOperations(taskOperations);
			}
		}
//		任务进度
		QueryWrapper<TaskStatusLog> taskStatusLogWrapper = WrapperUtils.getWrapper(false);
		taskStatusLogWrapper.eq("task_id", taskInfo.getId());
		taskStatusLogWrapper.ge("task_status", 3);
		taskStatusLogWrapper.orderByAsc("id");
		List<TaskStatusLog> taskStatusLogs = taskStatusLogService.list(taskStatusLogWrapper);
		if (StringUtil.isNotEmpty(taskStatusLogs)) {
			List<TaskProgress> taskProgresss = new ArrayList<TaskProgress>();
			for (TaskStatusLog taskStatusLog : taskStatusLogs) {
				TaskProgress taskProgress = new TaskProgress();
				BeanUtils.copyProperties(taskStatusLog, taskProgress);
				taskProgresss.add(taskProgress);
			}
			taskInfoDetailOutput.setTaskProgresss(taskProgresss);
		}
//		任务积分
		TaskPoint taskPoint = new TaskPoint();
		if (taskInfo.getPoint()>0) {
			if (taskInfo.getFinishTime() != null) {
				if (taskInfo.getStatus() == 5 || taskInfo.getStatus() == 6) {
					taskPoint.setCreateTime(taskInfo.getFinishTime());
					taskPoint.setPoint(taskInfo.getPoint());
					taskInfoDetailOutput.setTaskPoint(taskPoint);
				}
			}else {
				taskPoint.setCreateTime(null);
				taskPoint.setPoint(taskInfo.getPoint());
				taskInfoDetailOutput.setTaskPoint(taskPoint);
			}
		}
		return ResultResponseBeanUtil.success(taskInfoDetailOutput);
	}

//	@ApiOperation(value = "统计查询")
//	@RequestMapping(value = "/statistics", method = RequestMethod.POST)
//	public BaseOutput<TaskInfoStatisticsOutput> statistics(HttpServletRequest request, @RequestBody TaskInfoPageInput input) {
//		Long districtId = input.getDistrictId();
//		if (StringUtil.isNull(districtId)) {
//			return ResultResponseBeanUtil.fail("请选择站点");
//		}
//		TaskInfoStatisticsOutput taskInfoStatisticsOutput = new TaskInfoStatisticsOutput();
//		QueryWrapper<TaskInfo> wrapper = WrapperUtils.getWrapper(false);
//		wrapper = WrapperUtils.beanToWrapper(wrapper, input);
////		@ApiModelProperty(value = "任务总数")
//		int allTask = taskInfoService.count(wrapper);
//		taskInfoStatisticsOutput.setAllTask(allTask);
////		@ApiModelProperty(value = "待抢单任务数")
//		int waitFortask = 0;
////		@ApiModelProperty(value = "已接单任务数")
//		int acceptTask = 0;
////		@ApiModelProperty(value = "作业中任务数")
//		int operationTask = 0;
////		@ApiModelProperty(value = "按时完成任务数")
//		int onTimeTask = 0;
////		@ApiModelProperty(value = "超时完成任务数")
//		int onTimeOutTask = 0;
////		@ApiModelProperty(value = "未完成任务数")
//		int incompleteTask = 0;
////		@ApiModelProperty(value = "人工取消任务数")
//		int manualCancelTask = 0;
////		@ApiModelProperty(value = "系统取消任务数")
//		int systemCancelTask = 0;
//		return ResultResponseBeanUtil.success(taskInfoStatisticsOutput);
//	}

	@ApiOperation(value = "任务的优先级设置")
	@ResponseBody
	@AvoidRepeatSubmit
	@RequestMapping(value = "/setTaskTaskOrder", method = RequestMethod.POST)
	public BaseOutput<String> setTaskTaskOrder(HttpServletRequest request, @RequestBody TaskTaskOrderInsert input) {
		User user = UserUtils.getUser(request);
		if (input.getTaskId() == null || input.getTaskId() == 0) {
			return ResultResponseBeanUtil.fail("任务异常");
		}
		TaskInfo taskInfo = taskInfoService.getById(input.getTaskId());
		if (taskInfo == null) {
			return ResultResponseBeanUtil.fail("任务异常");
		}
		taskInfo.setTaskOrder(input.getTaskOrder());
		try {
			taskInfoService.updateById(taskInfo);
		} catch (Exception e) {
			e.printStackTrace();
			return ResultResponseBeanUtil.fail("操作失败");
		}
		return ResultResponseBeanUtil.success("操作成功");

	}
}
