package com.bcxin.survey.service.wechat;

import com.bcxin.survey.dao.QueryHelper;
import com.bcxin.survey.dao.report.BaseDao;
import com.bcxin.survey.domain.activity.Activity;
import com.bcxin.survey.domain.activity.ActivityVenue;
import com.bcxin.survey.domain.activity.Message;
import com.bcxin.survey.domain.activity.Venue;
import com.bcxin.survey.domain.dynamic.DynamicTemplateConst;
import com.bcxin.survey.domain.report.Task;
import com.bcxin.survey.domain.security.Org;
import com.bcxin.survey.domain.security.User;
import com.bcxin.survey.domain.survey.SurveyPlan;
import com.bcxin.survey.domain.survey.SurveyTask;
import com.bcxin.survey.domain.survey.Survey_FeedBack;
import com.bcxin.survey.domain.survey.Survey_Questionnaire;
import com.bcxin.survey.enums.report.*;
import com.bcxin.survey.service.CommonService;
import com.bcxin.survey.service.NotifyService;
import com.bcxin.survey.service.UserService;
import com.bcxin.survey.service.report.ActivityService;
import com.bcxin.survey.utils.*;
import com.bcxin.survey.utils.sms.SMSUtil;
import com.bcxin.survey.vo.EmailModel;
import com.bcxin.survey.vo.MessageModel;
import net.sf.json.JSONObject;
import org.hibernate.NullPrecedence;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
@Transactional
public class SurveyPlanServiceImpl implements SurveyPlanService {

	@Resource
	private BaseDao baseDao;
	@Autowired
	private CommonService commonService;
	
	@Resource
	private SurveyTaskService surveyTaskService;

	@Resource
	private SurveyFeedBackService surveyFeedBackService;

	@Resource
	private SurveyQuestionnaireService surveyQuestionnaireService;

	@Resource
	private UserService userService;

	@Resource
	private ActivityService activityService;

	@Resource
	private SurveyManagerUtil surveyManagerUtil;

	@Resource
	private NotifyService notifyService;

	@Override
	public boolean saveOrUpdate(SurveyPlan surveyPlan){
		boolean flag = true;
		try {
			surveyPlan.setUpdateOn(new Date());
			baseDao.saveOrUpdate(surveyPlan);		
		}catch(Exception e) {
			e.printStackTrace();
			flag = false;
		}
		return flag;
	}

	@Override
	public boolean delete(SurveyPlan surveyPlan) {
		boolean flag = true;
		try {
			baseDao.delete(surveyPlan);		
		}catch(Exception e) {
			flag = false;
		}
		return flag;
	}

	@Override
	public SurveyPlan findSurveyPlanByOid(long oid){
		return baseDao.get(SurveyPlan.class, oid);
	}



	@Override
	public List<SurveyPlan> findSurveyPlanByTaskId(long taskId){
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("surveyTask.oid", taskId));
		List<Order> orderList = new ArrayList<Order>();
		orderList.add(Order.asc("surveyTask.oid"));
		orderList.add(Order.asc("time"));
		return baseDao.findByCriterion(SurveyPlan.class, criterionList,orderList);
	}

	/**
	 *
	 * @param surveyTaskId
	 * @return
	 */
	@Override
	public List<Object> findSurveyPlanBySurveyTaskId(Long surveyTaskId){
		String sql="select \n" +
				"A.oid,A.time,\n" +
				"case A.surveyStep when 'FIRST' then 1\n" +
				"when 'SECOND' then 2 when 'THIRD' then 3 else '' end surveyStep,\n" +
				"case when A.allDay=1 then DATE_FORMAT(A.beginTime,'%Y-%m-%d')\n" +
				"else DATE_FORMAT(A.beginTime,'%Y-%m-%d %H:%i') end as beginTime,-- 踏勘开始时间\n" +
				"case when A.allDay=1 then DATE_FORMAT(A.endTime,'%Y-%m-%d')\n" +
				"else DATE_FORMAT(A.endTime,'%Y-%m-%d %H:%i') end as endTime, -- 踏勘结束时间\n" +
				"act.sponsor as contacts,\n" +
				"B.contactMobile,\n" +
				"A.taskStatus,\n" +
				"D.`name` as venueName,\n" +
				"E.tkExpert\n" +
				"from RISK_SurveyPlan A\n" +
				"inner join risk_surveytask B on A.taskId=B.oid\n" +
				"inner join sys_venue D on D.oid=A.venueId\n" +
				"inner join risk_activity act on act.oid=B.activityId\n"+
				"left join(\n" +
				"select M.surveyStep,M.taskId,CONCAT(N.realName,' ',N.phone) as tkExpert \n" +
				"from risk_survey_expert M,risk_se_user N where M.expertUserId=N.oid\n" +
				") E on (E.taskId=B.taskId and A.surveyStep=E.surveyStep)";
		sql+=" where B.oid="+surveyTaskId;
		sql+=" order by B.oid,A.time asc";
		List<Object> list = QueryHelper.findBySql(sql.toString(), null);
		for(Object obj : list){
			Map<String,Object> map=(Map<String,Object>)obj;
			if(map.containsKey("taskStatus")){
				map.put("taskStatusName",PlanStatusEnum.getAlias(map.get("taskStatus").toString()));
			}
			if(map.get("tkExpert")==null){
				map.put("tkExpert","--");
			}
		}
		return list;
	}



	@Override
	public JSONObject editSurveyPlan(SurveyPlan surveyPlan) {
		JSONObject obj = new JSONObject();
		String statusCode = "300";
		String message = "";
		
		String operationType = "添加";
		SurveyPlan plan;
		if(surveyPlan.getBeginTime().getTime() < System.currentTimeMillis()){
			message = "勘查时间应该晚于当前时间！";
		}
		else if(surveyPlan.getBeginTime().getTime()>surveyPlan.getEndTime().getTime()){
			message ="勘查开始时间应该小于结束时间！";
		}
		else{
			Survey_FeedBack feedBack = surveyFeedBackService.findSurveyFeedBackByTaskAndStep(surveyPlan.getSurveyTask(), surveyPlan.getSurveyStep()); 
			Survey_Questionnaire questionnaire = surveyQuestionnaireService.findQuestionnaireByFeedBackIdAndAddressId(feedBack.getOid(), surveyPlan.getVenue().getOid());
			Survey_Questionnaire oldQuestionnaire = null;
			if(surveyPlan.getOid() == null) {
				plan = findSurveyPlanByTaskAndTime(surveyPlan.getSurveyTask(), surveyPlan.getTime());
			}
			else{
				operationType = "修改";
				plan = findSurveyPlanByOid(surveyPlan.getOid());
				if(questionnaire == null){
					//重新完成计划问卷初始数据生成
					SurveyTask surveyTask = surveyTaskService.findSurveyTaskByOid(feedBack.getSurveyTask().getOid());
					List<Survey_FeedBack> feedBackList = surveyFeedBackService.findSurvey_FeedBackByTaskId(feedBack.getSurveyTask().getOid());
					for(Survey_FeedBack fb : feedBackList){
						if(FeedBackStatusEnum.NON.equals(fb.getTaskStatus())){
							List<ActivityVenue> list = activityService.findActivityVenuesByActivity(surveyTask.getActivity());
							for (ActivityVenue activityVenue : list) {
								Survey_Questionnaire q = surveyQuestionnaireService.findQuestionnaireByFeedBackIdAndAddressId(feedBack.getOid(), activityVenue.getVenue().getOid());
								if(q!=null){
									continue;
								}
								q = new Survey_Questionnaire();
								q.setVenue(activityVenue.getVenue());
								q.setCreateOn(new Date());
								q.setFeedBack(fb);
								q.setSurveyStep(fb.getSurveyStep());
								q.setTaskStatus(QuestionStatusEnum.NON);
								surveyQuestionnaireService.saveOrUpdate(q);
							}
						}
					}
					questionnaire = surveyQuestionnaireService.findQuestionnaireByFeedBackIdAndAddressId(feedBack.getOid(), surveyPlan.getVenue().getOid());
				}
				oldQuestionnaire = plan.getQuestionnaire();
			}
			if(plan == null){
				plan = new SurveyPlan();
				plan.setCreateOn(new Date());
				plan.setUser(surveyPlan.getUser());
				plan.setSurveyTask(surveyPlan.getSurveyTask());
				plan.setTaskStatus(PlanStatusEnum.NON);
			}
			
			plan.setSurveyStep(surveyPlan.getSurveyStep());
			plan.setTime(surveyPlan.getTime());
			plan.setFeedBack(feedBack);
			if(feedBack.getTaskStatus().equals(FeedBackStatusEnum.COMPLETE)){
				feedBack.setTaskStatus(FeedBackStatusEnum.NON);
				surveyFeedBackService.saveOrUpdate(feedBack);
			}
			
			if(questionnaire != null && questionnaire.getTaskStatus().equals(QuestionStatusEnum.COMPLETE)){
				questionnaire.setTaskStatus(QuestionStatusEnum.CONTINUE);
				surveyQuestionnaireService.saveOrUpdate(questionnaire);
			}
			plan.setQuestionnaire(questionnaire);
			plan.setVenue(surveyPlan.getVenue());
			plan.setRemark(surveyPlan.getRemark());
			plan.setAllDay(surveyPlan.isAllDay());
			plan.setBeginTime(surveyPlan.getBeginTime());
			plan.setEndTime(surveyPlan.getEndTime());
				
			if(saveOrUpdate(plan)){
				statusCode = "200";
				planListForSort(surveyPlan.getSurveyTask().getOid());
				message = operationType + "成功，现场勘查前还需维护勘查问卷";
				obj.put("taskId", surveyPlan.getSurveyTask().getOid());

				//发送通知给勘查项目经理和勘查区域经理
				SurveyTask surveyTask = plan.getSurveyTask();

				if (surveyTask != null) {

					//获取第几阶段
					String step = "";
					if (surveyPlan.getSurveyStep().equals(SurveyStep.FIRST)) {
						step = SurveyStep.FIRST.getName();
					} else if (surveyPlan.getSurveyStep().equals(SurveyStep.SECOND)) {
						step = SurveyStep.SECOND.getName();
					} else if (surveyPlan.getSurveyStep().equals(SurveyStep.THIRD)) {
						step = SurveyStep.THIRD.getName();
					}

					Venue venue = plan.getVenue();

					Venue venue1 = activityService.selectVenueById(venue.getOid());

					Activity activity = surveyManagerUtil.selectActivity(surveyTask);

					activity = activityService.findActivityByOid(activity.getOid());

					Task task = surveyManagerUtil.selectTaskBySurveyTask(surveyTask);
					User user = userService.getCurrentUser();

					if (user != null && activity != null && task != null && venue1 != null) {
						String surveyTime="";
						if(surveyPlan.isAllDay()){
							String beginTime=DateUtil.convertDateToString(surveyPlan.getBeginTime(), DateUtil.FORMAT2);
							String endTime=DateUtil.convertDateToString(surveyPlan.getEndTime(), DateUtil.FORMAT2);
							surveyTime=beginTime+"~"+endTime;
						}else{
							String beginTime=DateUtil.convertDateToString(surveyPlan.getBeginTime(), DateUtil.FORMAT7);
							String endTime=DateUtil.convertDateToString(surveyPlan.getEndTime(), DateUtil.FORMAT7);
							surveyTime=beginTime+"~"+endTime;
						}

						Org org=commonService.getOrg(activity);

						//查询服务机构注册人员信息
						User serviceOrgRegister = userService.selectServiceOrgRegister(org);

						//查询服务机构多类人员信息
						List<String> userTypeList = new ArrayList<>();
						userTypeList.add(DictConst.USERTYPE_DSFFWJGYH_ZG);
						userTypeList.add(DictConst.USERTYPE_DSFFWJGYH_TKXMJL);
						userTypeList.add(DictConst.USERTYPE_DSFFWJGYH_TKQYJL);

						List<User> serviceOrgPersonList = userService.selectServiceOrgPersonByList(userTypeList, org.getOid());

						serviceOrgPersonList.add(serviceOrgRegister);

						//活动承办方
						User activityUser = activity.getUser();

						serviceOrgPersonList.add(activityUser);

						for (User pm : serviceOrgPersonList) {
							//手机短信通知
							String content = user.getRealName() + "已为" + activity.getName() + "新增" + step + "计划。" +
									"勘查时间：" + surveyTime + "，勘查地点：" + venue1.getName() + "。";
							notifyService.sendHuaWeiSMS(pm.getPhone(),content, Const.ENVI_TK, DictConst.SMSCODE_B09,new String[]{user.getRealName(), activity.getName(),surveyTime,venue1.getName()});
							//邮件通知
							EmailModel model = new EmailModel();
							model.setSubject(activity.getName() + "已新增勘查计划");
							model.setEmailType(EmailMsgType.SURVEYTASK);
							model.setContent(user.getRealName() + "已为" + activity.getName() + "新增" + step + "计划。" +
									"勘查时间：" + surveyTime + "，勘查地点：" + venue1.getName() + "。【" + SMSUtil.platFormName() + "】");
							model.setTo(pm.getEmail());
							notifyService.sendEmail(model);

							//站内信
							Message msg = new Message();
							msg.setUser_id(pm.getOid());
							msg.setReadStatus("0");
							msg.setContent(user.getRealName() + "已为" + activity.getName() + "新增" + step + "计划。" +
									"勘查时间：" + surveyTime + "，勘查地点：" + venue1.getName() + "。");
							msg.setTitle(activity.getName() + "新增了勘查计划");
							msg.setKeyword("立即查看");
							msg.setUrl("/survey/task/detail/" + task.getOid());
							msg.setCreateOn(new Date());
							baseDao.saveOrUpdate(msg);

						}

						// 保存计划到动态看板
						DynamicUtil.getBean().saveTKPlanData(user,DynamicTemplateConst.DYNAMIC_TEMP_KANCHA_400010,activity.getOid(),step,surveyTime,venue1.getName());
					}
				}

			}else{
				message = operationType +"失败";
			}
			if(statusCode.equals("200")){
				if(oldQuestionnaire != null && (oldQuestionnaire.getTaskStatus().equals(QuestionStatusEnum.NON) || oldQuestionnaire.getTaskStatus().equals(QuestionStatusEnum.CONTINUE))
						&& !oldQuestionnaire.getOid().equals(questionnaire.getOid())){
					surveyFeedBackService.checkFeedBackStatusByQuestionnaireId(oldQuestionnaire.getOid());
				}
			}
		}
		obj.put("statusCode", statusCode);
		obj.put("message", message);
		return obj;
	}

	private SurveyPlan findSurveyPlanByTaskAndTime(SurveyTask surveyTask, int time) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("surveyTask.oid", surveyTask.getOid()));
		criterionList.add(Restrictions.eq("time", time));
		List<SurveyPlan> list = baseDao.findByCriterion(SurveyPlan.class, criterionList);
		if(list != null && list.size() >0) {
			return list.get(0);
		}
		return null;
	}



	@Override
	public List<SurveyPlan> findSurveyPlanListByUserAndDate(User user, Date beginTime, Date endTime) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("user", user));	
		criterionList.add(Restrictions.ge("beginTime", beginTime));
		criterionList.add(Restrictions.le("endTime", endTime));
		List<Order> orderList = new ArrayList<Order>();
		orderList.add(Order.asc("surveyTask.oid"));
		orderList.add(Order.asc("time"));
		return baseDao.findByCriterion(SurveyPlan.class, criterionList, orderList);
	}

	@Override
	public void planListForSort(long taskId){
		List<SurveyPlan> planList = findSurveyPlanListBySurveyTaskId(taskId);
		int time = 1;
		for (SurveyPlan surveyPlan : planList) {
			surveyPlan.setTime(time);
			saveOrUpdate(surveyPlan);
			time++;
		}
	}


	@Override
	public List<SurveyPlan> findSurveyPlanListBySurveyTaskId(long taskId) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("surveyTask.oid", taskId));	
		List<Order> orderList = new ArrayList<Order>();
		orderList.add(Order.asc("beginTime").nulls(NullPrecedence.LAST));
		orderList.add(Order.asc("time"));
		return baseDao.findByCriterion(SurveyPlan.class, criterionList, orderList);
	}

	@SuppressWarnings("unchecked")
	@Override
	public SurveyPlan findSurveyPlanByTaskIdAndTime(long taskId, int time) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("surveyTask.oid", taskId));	
		criterionList.add(Restrictions.eq("time", time));	
		List<SurveyPlan> surveyPlans = baseDao.findByCriterion(SurveyPlan.class, criterionList);
		if(surveyPlans != null && surveyPlans.size()>0) {
			return surveyPlans.get(0);
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<SurveyPlan> findSurveyPlanListByFeedBackId(long feedBackId) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("feedBack.oid", feedBackId));	
		return baseDao.findByCriterion(SurveyPlan.class, criterionList);
	}

	@Override
	public List<SurveyPlan> findSurveyPlanListByFeedBackId(Long feedBackId, Long venueId) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("feedBack.oid", feedBackId));	
		criterionList.add(Restrictions.eq("venue.oid", venueId));	
		return baseDao.findByCriterion(SurveyPlan.class, criterionList);
	}

	@Override
	public List<SurveyPlan> findSurveyPlanListByQuestionnaireId(Long questionnaireId) {
		List<Criterion> criterionList = new ArrayList<Criterion>();
		criterionList.add(Restrictions.eq("questionnaire.oid", questionnaireId));	
		return baseDao.findByCriterion(SurveyPlan.class, criterionList);
	}
}
