package com.yeejoin.amos.patrol.business.service.impl;

import com.yeejoin.amos.boot.biz.common.bo.ReginParams;
import com.yeejoin.amos.feign.privilege.model.AgencyUserModel;
import com.yeejoin.amos.patrol.business.dao.mapper.CheckMapper;
import com.yeejoin.amos.patrol.business.dao.mapper.TaskMapper;
import com.yeejoin.amos.patrol.business.dao.mapper.TaskPictureMapper;
import com.yeejoin.amos.patrol.business.dao.repository.*;
import com.yeejoin.amos.patrol.business.entity.mybatis.PointCheckDetailBo;
import com.yeejoin.amos.patrol.business.entity.mybatis.TaskBo;
import com.yeejoin.amos.patrol.business.entity.mybatis.TaskFeedbackBo;
import com.yeejoin.amos.patrol.business.param.*;
import com.yeejoin.amos.patrol.business.service.intfc.ITaskService;
import com.yeejoin.amos.patrol.business.util.DaoCriteria;
import com.yeejoin.amos.patrol.business.util.ToolUtils;
import com.yeejoin.amos.patrol.business.vo.CheckTaskDetailVo;
import com.yeejoin.amos.patrol.business.vo.TaskDetailVo;
import com.yeejoin.amos.patrol.business.vo.TaskStatisticsVo;
import com.yeejoin.amos.patrol.common.enums.TaskFeedbackType;
import com.yeejoin.amos.patrol.common.enums.TaskStatusEnum;
import com.yeejoin.amos.patrol.core.common.response.AppPointCheckRespone;
import com.yeejoin.amos.patrol.core.util.query.BaseQuerySpecification;
import com.yeejoin.amos.patrol.dao.entity.*;
import com.yeejoin.amos.patrol.exception.YeeException;
import com.yeejoin.amos.patrol.feign.RemoteSecurityService;
import com.yeejoin.amos.patrol.quartz.IJobService;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.apache.commons.collections.CollectionUtils;
import org.quartz.JobDataMap;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import javax.transaction.Transactional;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Pattern;


@Service("taskService")
public class TaskServiceImpl implements ITaskService {

	@Autowired
	ITaskPictureDao taskPictureDao;
	@Autowired
	ITaskDao taskDao;
	@Autowired
	ITaskDetailDao taskDetailDao;
	@Autowired
	ITaskFeedbackDao taskFeedbackDao;
	@Autowired
	ITaskForwardLogDao taskForwardLogDao;
	/*@Autowired
	IUserDao userDao;*/
	@Resource
	TaskMapper taskMapper;
	@Resource
	TaskPictureMapper taskPictureMapper;
	@Autowired
    private RemoteSecurityService remoteSecurityService;

	@Autowired
	private IJobService jobService;
	@Resource
	ICheckShotDao checkShotDao;

	@Autowired
	private CheckMapper checkMapper;

//	@Value("${LatentDanger.flow.photoUrls}")
//	private String photoUrl;
//    @Value("${file.url}")
//    private String fileUrl;
	@Override
	@Transactional
	public Long addNewTask(TaskParam param) {
//		SUser executor = userDao.findOne(param.getTaskInfo().getExecutor());
//		param.getTaskInfo().setExecutorId(executor.getId());
		Task taskVo = new Task();
		TaskInfoParam info=param.getTaskInfo();
		if(info.getDepId()!=null&&info.getDepId().length()<6){
			info.setDepId(null);
		}
		BeanUtils.copyProperties(param.getTaskInfo(), taskVo);
		taskVo.setCreateDate(new Date());
		taskVo.setConfig(param.getTaskInfo().getConfig().toJSONString());
		Task task = taskDao.saveAndFlush(taskVo);
		long id = task.getId();
		jobService.taskAddJob(task);
		if (ObjectUtils.isEmpty(param.getTaskDetails())) {
			return id;
		}
		List<TaskDetail> details = new ArrayList<>();
		long pointId =0;
		for(Iterator iterators = param.getTaskDetails().iterator(); iterators.hasNext();){
			TaskDetailParam detailParam = (TaskDetailParam) iterators.next();
			pointId = detailParam.getPointId();
			TaskDetail detail = new TaskDetail();
			BeanUtils.copyProperties(detailParam, detail);
			detail.setTaskId(id);
			detail.setCreateDate(new Date());
			// 缺巡检点 巡检路线 数据填充
			details.add(detail);

		}
		task.setPointId(pointId);
		taskDao.save(task);
		taskDetailDao.saveAll(details);
		return id;
	}

	@Override
	public TaskBo queryTaskDetail(Long taskID) {
		TaskBo bo = new TaskBo();
		Task taskInfo = taskDao.findById(taskID).get();
		List<TaskDetailVo> taskDetail = taskMapper.findByTaskDetailId(taskID);
		if(!taskDetail.isEmpty()){
			taskInfo.setIsScan(taskDetail.get(0).getIsFixed().equals("1")?true:false);
		}
		bo.setTaskInfo(taskInfo);
		bo.setTaskDetails(taskDetail);
		Specification specification = getSpecification(taskID);
		List<TaskFeedback> feedbacks = taskFeedbackDao.findAll(specification);
		if (ObjectUtils.isEmpty(feedbacks)) {
			bo.setFeedback(new ArrayList<>());
			return bo;
		}
		List<TaskFeedbackBo> feedbackList = new LinkedList<TaskFeedbackBo>();
		for (TaskFeedback feedback: feedbacks) {
			TaskFeedbackBo feedbackBo = new TaskFeedbackBo();
			BeanUtils.copyProperties(feedback, feedbackBo);

			if(feedback.getUserId()!=null){
				feedbackBo.setUserId(Integer.valueOf(feedback.getUserId()));

			}
			 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
			List<String> list = new ArrayList<>();
			List<String> picList = taskPictureMapper.queryTaskFeedbackPic(feedback.getId());
			for (int i = 0; i <picList.size() ; i++) {
//				list.add(fileUrl+ picList.get(i));
				list.add(picList.get(i));
			}
			feedbackBo.setFeedbackPics(list);
			feedbackList.add(feedbackBo);
		}
		bo.setFeedback(feedbackList);
		return bo;
	}


	@Override
	@Transactional
	public void updateTask(TaskParam param) {
		Task taskVo = new Task();
		BeanUtils.copyProperties(param.getTaskInfo(), taskVo);
		taskMapper.updateTask(taskVo);
		List<TaskDetail> list = taskDetailDao.findByTaskId(param.getTaskInfo().getId());
		for (TaskDetailParam detailParam : param.getTaskDetails()) {
			if (detailParam.getId() <= 0) { // 如果为新增巡检项则新增
				TaskDetail detail = new TaskDetail();
				BeanUtils.copyProperties(detailParam, detail);
				detail.setTaskId(param.getTaskInfo().getId());

				// 缺巡检点 巡检路线 数据填充

				taskDetailDao.save(detail);
			} else {
				taskMapper.updateTaskDetail(detailParam);
			}
		}
		// 删除未勾选的巡检项
		if (ObjectUtils.isEmpty(list)) {
			return;
		}
		Iterator<TaskDetail> it = list.iterator();
		while(it.hasNext()){
			TaskDetail x = it.next();
			for (TaskDetailParam detailParam : param.getTaskDetails()) {
				if (x.getId() == detailParam.getId()) {
					it.remove();
					break;
				}
			}
		}
		if (!list.isEmpty()) {
			taskDetailDao.deleteInBatch(list);
		}
	}

	@Override
	@Transactional
	public void delTask(Long taskID) {
		Task task = taskDao.findById(taskID).get();
		if(task.getStatus()!=TaskStatusEnum.CANCEL.getValue()){
			throw new YeeException("任务状态处于【已取消】才可删除！");
		}
		List<TaskDetail> taskDetaillist = taskDetailDao.findByTaskId(taskID);
		List<TaskFeedback> taskFeedbacks = taskFeedbackDao.findAllByTaskId(taskID);
		List<TaskForwardLog> taskForwardLogs = taskForwardLogDao.findAllByTaskId(taskID);
		List<TaskPicture> taskPictures = taskPictureDao.findAllByTaskId(taskID);
		taskPictureDao.deleteInBatch(taskPictures);
		taskForwardLogDao.deleteInBatch(taskForwardLogs);
		taskFeedbackDao.deleteInBatch(taskFeedbacks);
		taskDetailDao.deleteInBatch(taskDetaillist);
		taskDao.deleteById(taskID);
	}

	@Override
	@Transactional
	public Task feedbackTask(TaskFeedback taskFeedback, List<TaskPicture> pictures) {
		Task task = taskDao.findById(taskFeedback.getTaskId()).isPresent()?taskDao.findById(taskFeedback.getTaskId()).get():null;
		if(task!=null){

		String config = task.getConfig();
		JSONArray parse = JSONArray.fromObject(config);
		String isMust="";
		if(parse.size()>0){
			JSONObject  cfg = parse.getJSONObject(0);
			isMust = cfg.get("isMust").toString();
		}
		taskFeedback = taskFeedbackDao.saveAndFlush(taskFeedback);
		if ("是".equals(isMust) && ObjectUtils.isEmpty(pictures)) {
			return null;
		}
		for (int i = 0; i < pictures.size(); i++) {
			pictures.get(i).setFeedbackId(taskFeedback.getId());
		}
		taskPictureDao.saveAll(pictures);
		task.setStatus(TaskStatusEnum.FINISHED.getValue());
		task.setFeedbackNum(task.getFeedbackNum() + 1);
		task.setFactFinishTime(new Date());
		taskDao.save(task);
		}
		return task;
	}

	@Override
	@Transactional
	public void forwardTask(String toke,String product,String appKey,Long taskId, AgencyUserModel user, String targetUserId) throws Exception {
		Task t = taskDao.findById(taskId).get();

		if(TaskStatusEnum.UNDERWAY.getValue() != t.getStatus()){
			throw new Exception("任务状态处于“处理中”才可进行转发！");
		}
		if (t.getMaxDepth() != 0 && t.getMaxDepth() <= t.getDepth()) {  // 判断任务时候已经到达最大转发数
			throw new Exception("已超出最大转发个数");
		}
        AgencyUserModel suser = remoteSecurityService.getUserById( toke, product, appKey,targetUserId);

		//SUser suser = userDao.findOne(targetUserId);
		t.setExecutorId(suser.getUserId());
		t.setExecutor(suser.getRealName());
		t.setDepth(t.getDepth() + 1);
		taskDao.save(t); // 修改任务信息

		TaskForwardLog log = new TaskForwardLog();
		log.setTaskId(t.getId());
		log.setExecutor(suser.getRealName());
		log.setExecutorId(suser.getUserId());
		log.setCreateDate(new Date());
		log.setContent(user.getRealName() + " 转发任务 " + t.getTitle() +" 至   " + suser.getRealName());
		log.setCreatedBy(Integer.valueOf(user.getUserId() + ""));
		taskForwardLogDao.save(log); // 记录任务转发信息
		TaskFeedback taskFeedback = new TaskFeedback();
		taskFeedback.setUserId(user.getUserId());
		taskFeedback.setMessage(user.getRealName() + " 转发任务 " + t.getTitle() +" 至  " + suser.getRealName());
		taskFeedback.setCreateDate(new Date());
		taskFeedback.setUserName(user.getRealName());
		taskFeedback.setFeedbackTime(new Date());
		taskFeedback.setOrgCode(user.getCompanys().get(0).getOrgCode());
		taskFeedback.setTaskId(t.getId());
		taskFeedback.setMessageType(TaskFeedbackType.FORWARD.getName());
		taskFeedback = taskFeedbackDao.save(taskFeedback);
	}

	@Override
	public Page<HashMap<String,Object>> queryTaskByPage(String toke,String product,String appKey,TaskPageParam param) {
		long total = taskMapper.countTaskInfoData(param);
		List<HashMap<String,Object>> content = taskMapper.getTaskPageInfo(param);


		    String userIds = "";

	        Set<String> set = new HashSet<>();
	        content.forEach(s -> {
	            if (s.containsKey("executorId")) {
	                set.add(s.get("executorId").toString());
	            }

	        });
	        List<String> userList = new ArrayList<>(set);
	        Map<String, Object> userMap = new HashMap<>();
		 if (!CollectionUtils.isEmpty(userList)) {
	            userIds = String.join(",", userList);
	            List<AgencyUserModel> userModelList = remoteSecurityService.listUserByUserIds( toke, product, appKey,userIds);
	            if(userModelList!=null&&userModelList.size()>0){
	            	for (AgencyUserModel agencyUserModel : userModelList) {
	            		userMap.put(agencyUserModel.getUserId(), agencyUserModel.getMobile());
					}
	            }
	        }

	        content.forEach(c -> {
	        	  if (userMap.containsKey(c.get("executorId"))) {
	        		  c.put("telep", userMap.get(c.get("executorId")));
		            }

	        });


		Page<HashMap<String,Object>> result = new PageImpl<HashMap<String,Object>>(content, param, total);
		return result;
	}

	@Override
	public List<Task> queryTaskByCondition(List<DaoCriteria> criterias) {
		BaseQuerySpecification<Task> specification = new BaseQuerySpecification<>(criterias);
		return taskDao.findAll(specification);
	}

	@Override
	public int queryTaskCountByCondition(List<DaoCriteria> criterias) {
		BaseQuerySpecification<Task> specification = new BaseQuerySpecification<>(criterias);
		return Integer.parseInt(taskDao.count(specification)+"");
	}


	/**
	 *	 根据任务id构建查询任务回复信息查询条件
	 * @param params
	 * @return
	 */
	private Specification getSpecification(Long taskId) {
		return new Specification<TaskFeedback>() {  // 构建查询条件
			@Override
			public Predicate toPredicate(Root<TaskFeedback> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				 List<Predicate> predicate = new ArrayList<>();
				 if (!ObjectUtils.isEmpty(taskId)) {
					 predicate.add(cb.equal(root.get("taskId").as(String.class), taskId));
				 }
				 Predicate[] pre = new Predicate[predicate.size()];
				 return query.where(predicate.toArray(pre)).getRestriction();
			}
		};
	}

	/**
	 *	 根据任务id构建查询任务回复信息查询条件
	 * @param params
	 * @return
	 */
	private Specification getFeedBackPicSpecification(Long feedbackId) {
		return new Specification<TaskPicture>() {  // 构建查询条件
			@Override
			public Predicate toPredicate(Root<TaskPicture> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				 List<Predicate> predicate = new ArrayList<>();
				 if (!ObjectUtils.isEmpty(feedbackId)) {
					 predicate.add(cb.equal(root.get("feedbackId").as(String.class), feedbackId));
				 }
				 Predicate[] pre = new Predicate[predicate.size()];
				 return query.where(predicate.toArray(pre)).getRestriction();
			}
		};
	}
	@Transactional
	@Override
	public void batchDelTask(String taskIDs) {
		if (ObjectUtils.isEmpty(taskIDs)) {
			return;
		}
		String[] ids = taskIDs.split(",");
		for (String id: ids) {
			if (ObjectUtils.isEmpty(id) && !isInteger(id)) {
				continue;
			}
			Long taskId = Long.valueOf(id);
			Task task = taskDao.findById(Long.valueOf(id)).get();
			if(task != null){
				if(task.getStatus()!=TaskStatusEnum.CANCEL.getValue()){
					throw new YeeException("任务状态处于【已取消】才可删除！");
				}
				List<TaskDetail> taskDetaillist = taskDetailDao.findByTaskId(taskId);
				List<TaskFeedback> taskFeedbacks = taskFeedbackDao.findAllByTaskId(taskId);
				List<TaskForwardLog> taskForwardLogs = taskForwardLogDao.findAllByTaskId(taskId);
				List<TaskPicture> taskPictures = taskPictureDao.findAllByTaskId(taskId);
				taskPictureDao.deleteInBatch(taskPictures);
				taskForwardLogDao.deleteInBatch(taskForwardLogs);
				taskFeedbackDao.deleteInBatch(taskFeedbacks);
				taskDetailDao.deleteInBatch(taskDetaillist);
				taskDao.deleteById(taskId);
			}

		}
	}

	  private boolean isInteger(String str) {
	      Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
	      return pattern.matcher(str).matches();
	  }

	@Transactional
	@Override
	public void handleTask(String taskIds, int status, AgencyUserModel user, String orgCode) {
		if (ObjectUtils.isEmpty(taskIds)) {
			return;
		}
		String[] ids = taskIds.split(",");
		for (String id: ids) {
			if (ObjectUtils.isEmpty(id) && !isInteger(id)) {
				continue;
			}
			Task task = taskDao.findById(Long.parseLong(id)).get();
			int taskStatus = task.getStatus();
			if(status == TaskStatusEnum.CANCEL.getValue() &&
					taskStatus ==TaskStatusEnum.FINISHED.getValue()){
				throw new YeeException("任务状态处于【处理中】或【已超时】才可进行【取消】操作！");
			}
			task.setStatus(status);
			taskDao.save(task);

			TaskFeedback taskFeedback = new TaskFeedback();
			taskFeedback.setUserId(user.getUserId());
			taskFeedback.setMessage(user.getUserName() + " 将任务 " + task.getTitle() +" 变更为  " + TaskStatusEnum.getName(status));
			taskFeedback.setCreateDate(new Date());
			taskFeedback.setUserName(user.getUserName());
			taskFeedback.setFeedbackTime(new Date());
			taskFeedback.setOrgCode(orgCode);
			taskFeedback.setTaskId(task.getId());
			taskFeedback.setMessageType(TaskStatusEnum.getName(status));
			taskFeedback = taskFeedbackDao.save(taskFeedback);
		}


	}

	@Override
	public Map queryTaskCharts(HashMap<String, Object> request) {
		return taskMapper.queryTaskCharts(request);
	}

	@Override
	public String job(JobDataMap jobDataMap) {
		// TODO Auto-generated method stub
		String jobName = (String) jobDataMap.get("jobName");
		System.out.println("jobName==="+jobName+"执行相关操作");
		return jobName;
	}

	@Override
	public List<Map> queryTasks(HashMap<String, Object> request) {
		return taskMapper.queryTasks(request);
	}

	@Override
	public HashMap<String, List<HashMap<String, Object>>> getHiddenDangerCountData(HashMap<String, Object> params) {
		List<HashMap<String, Object>> yearConutList = taskMapper.getHidDangerCtDtOfYear(params);//年度统计
		List<HashMap<String, Object>> monthConutList = taskMapper.getHidDangerCtDtOfMonth(params);//月统计
		List<HashMap<String, Object>> curConutList = taskMapper.getHidDangerCtDtOfCur(params);//当前统计

		List<Map<String,String>> taskEnums = TaskStatusEnum.getEnumList();
		List<String> complement = new ArrayList<>();
		List<HashMap<String, Object>> conutList = new ArrayList<>();
		for (Map<String, String> map : taskEnums) {
			boolean isCreate = true;
			for (HashMap<String, Object> hashMap : curConutList) {
				if(map.get("name").equals(hashMap.get("name"))) {
					isCreate = false;
					conutList.add(hashMap);
				}
			}
			if (isCreate) {
				HashMap<String, Object> temp = new HashMap<>();
				temp.put("name", map.get("name"));
				temp.put("value",0);
				conutList.add(temp);
			}
		}
//		for (String str : complement) {
//			HashMap<String, Object> newVal = new HashMap<>();
//			newVal.put("name", str);
//			newVal.put("value", 0);
//			curConutList.add(0, newVal);
//			//curConutList.add(newVal);
//		}
//

		HashMap<String, List<HashMap<String, Object>>> map= new HashMap<String, List<HashMap<String, Object>>>();
		map.put("yearConutList", yearConutList);
		map.put("monthConutList", monthConutList);
		map.put("curConutList", conutList);
		return map;
	}

	@Override
	public List<HashMap<String, Object>> getPointIDsByRouteIDs(List<String> routeID) {
		List<HashMap<String, Object>> routeIDAndPointIDs = taskMapper.getPointIDsByRouteIDs(routeID);
		return routeIDAndPointIDs;
	}

	@Override
	public Map<String, Object> getTaskForAppPie(HashMap<String, Object> params) {
		return taskMapper.getTaskForAppPie(params);
	}

	@Override
	public List<TaskStatisticsVo> getTaskStatistics(TaskStatisticsParam param) {
		return taskMapper.getTaskStatistics(param);
	}

	@Override
	public String getTaskFinishCountByOrgCode(String loginOrgCode) {
		return taskMapper.getTaskFinishCountByOrgCode(loginOrgCode);
	}

	@Override
	public List<TaskFeedback> queryTaskRecord(Long taskID) {
		Specification specification = getSpecification(taskID);
		List<TaskFeedback> feedbacks = taskFeedbackDao.findAll(specification);
		return feedbacks;
	}

	@Override
	public Map<String, Object> queryCheckTaskDetail(long checkId, long taskId) {
		List<CheckTaskDetailVo> details = taskMapper.queryCheckTaskInputItems(checkId, taskId);
		List<CheckShot> pointShot = checkShotDao.findAllByCheckIdAndCheckInputIdAndClassifyId(checkId,0l,0l);
		Map<String, Object> resp = new HashMap<String, Object>();
		AppPointCheckRespone pointCheckRespone =  new  AppPointCheckRespone();
		List<String> pointImgUrls = new ArrayList<>();

		pointShot.forEach(action->{
			pointImgUrls.add(action.getPhotoData());
		});

		List<PointCheckDetailBo> list = checkMapper.findCheckPointInputItem(checkId);
		if (ObjectUtils.isEmpty(list)) {
			return null;
		}
		PointCheckDetailBo pointCheckDetailBo = list.get(0);
		pointCheckRespone.setPointId(pointCheckDetailBo.getPointId());
		pointCheckRespone.setPointName(pointCheckDetailBo.getPlanName());
		pointCheckRespone.setPointNo(pointCheckDetailBo.getPointNo());
		pointCheckRespone.setPointStatus(pointCheckDetailBo.getPointStatus());
		pointCheckRespone.setPlanName(pointCheckDetailBo.getPlanName());
		pointCheckRespone.setDepartmentName(pointCheckDetailBo.getDepartmentName());
		pointCheckRespone.setUsername(pointCheckDetailBo.getUsername());
		pointCheckRespone.setCheckTime(pointCheckDetailBo.getCheckTime());
		pointCheckRespone.setCheckId(pointCheckDetailBo.getCheckId());
		pointCheckRespone.setPointImgUrls(pointImgUrls);
		resp = ToolUtils.transBean2Map(pointCheckRespone);
		resp.put("task",taskDao.findById(taskId).get());
		resp.put("checkInput", details);

		return resp;
	}

	@Override
	public List<Map<String, Object>> synchronizedOfflineTasks(AgencyUserModel user, ReginParams reginParams) {
		Map<String, Object> request = new HashMap<String, Object>();
		request.put("executorId", user.getUserId());
		request.put("orgCode",reginParams.getCompany().getOrgCode());
		request.put("status", 0);
		List<Map<String, Object>> taskList = taskMapper.synchronizedOfflineTasks(request);
		return taskList;
	}
}
