package com.yihu.wlyy.web.patient.consult;

import java.util.*;

import com.yihu.wlyy.entity.consult.ConsultTeam;
import com.yihu.wlyy.entity.consult.ConsultTeamLog;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.doctor.schedule.WlyyDoctorWorkTime;
import com.yihu.wlyy.entity.doctor.schedule.WlyyDoctorWorkWeek;
import com.yihu.wlyy.service.app.scheduling.DoctorWorkTimeService;
import io.swagger.annotations.Api;
import org.apache.commons.lang3.StringUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.yihu.wlyy.service.app.consult.ConsultTeamService;
import com.yihu.wlyy.service.app.consult.DoctorCommentService;
import com.yihu.wlyy.service.app.statistics.DoctorStatisticsService;
import com.yihu.wlyy.service.app.talk.TalkGroupService;
import com.yihu.wlyy.service.common.account.DoctorService;
import com.yihu.wlyy.task.DoctorStatisticsTask;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.CommonUtil;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.MessageType;
import com.yihu.wlyy.web.WeixinBaseController;

/**
 * 患者端：三师咨询控制类
 * @author George
 *
 */
@Controller
@RequestMapping(value = "/patient/consult")
@Api(description = "患者端-患者咨询")
public class ConsultController extends WeixinBaseController {

	@Autowired
	private ConsultTeamService consultTeamService;
	@Autowired
	private DoctorCommentService doctorCommentService;
	@Autowired
	private DoctorStatisticsService doctorStatisticsService;
    @Autowired
	private DoctorService doctorService;
	@Autowired
	private TalkGroupService talkGroupService;
	@Autowired
	private DoctorWorkTimeService doctorWorkTimeService;

	/**
	 * 患者咨询记录查询
	 * @param title 咨询标题
	 * @param id
	 * @param pagesize 分页大小
	 * @return
	 */
	@RequestMapping(value = "records")
	@ResponseBody
	public String consultRecords(
			@RequestParam(required = false) String  title,
			long id,
			int pagesize) {
		try {
			JSONArray array = new JSONArray();
			Page<Object> data = consultTeamService.findConsultRecordByPatient(getUID(), id, pagesize,title);
			if (data != null) {
				for (Object consult : data.getContent()) {
					if (consult == null) {
						continue;
					}
					Object[] result = (Object[])consult;
					JSONObject json = new JSONObject();
					json.put("id", result[0]);
					// 设置咨询类型：1三师咨询，2视频咨询，3图文咨询，4公共咨询，5病友圈
					json.put("type", result[1]);
					// 设置咨询标识
					json.put("code", result[2]);
					// 设置显示标题
					json.put("title", result[3]);
					// 设置主诉
					json.put("symptoms", result[4]);
					// 咨询状态
					json.put("status", result[6]);
					// 设置咨询日期
					json.put("czrq", DateUtil.dateToStrLong((Date)result[5]));
					array.put(json);
				}
			}
			return write(200, "查询成功！", "list", array);
		} catch (Exception e) {
			error(e);
			return error(-1, "查询失败！");
		}
	}

	/**
	 * 获取医生的排班时间
	 *
	 * @param doctor
	 * @param week
	 * @return
	 */
	@RequestMapping(value = "/doctor_worktime/week")
	@ResponseBody
	public String getDoctorWeekWorkTime(String doctor,String week){
		try{
			JSONObject result = doctorWorkTimeService.findDoctorWeekWorkTime(doctor,week);

			return write(200,"查询成功!","data",result);
		}catch (Exception e){
			e.printStackTrace();
			return error(-1,"查询失败!");
		}
	}

	/**
	 * 获取医生某天的排班时间
	 *
	 * @param doctor
	 * @return
	 */
	@RequestMapping(value = "/doctor_worktime")
	@ResponseBody
	public String getDoctorWorkTime(String doctor){
		try{
			JSONObject result = doctorWorkTimeService.findDoctorWorkTime(doctor);

			return write(200,"查询成功!","data",result);
		}catch (Exception e){
			e.printStackTrace();
			return error(-1,"查询失败!");
		}
	}

    /**
     * 医生是否在工作
     *
     * @param doctor
     * @return
     */
    @RequestMapping(value = "is_doctor_working")
    @ResponseBody
	public String isDoctorAtWorking(String doctor){
		try{
            JSONObject result = doctorWorkTimeService.isDoctorWorking(doctor);
            return write(200,result.getString("msg"),"data",result.getString("status"));
		}catch (Exception e){
            e.printStackTrace();
			return error(-1,"查询失败");
		}
	}

	/**
	 * 名医是否在工作
	 *
	 * @param doctor
	 * @return
	 */
	@RequestMapping(value = "is_famous_doctor_working")
	@ResponseBody
	public String isFamousDoctorAtWorking(String doctor){
		try{
			JSONObject result = doctorWorkTimeService.isFamousDoctorWorking(doctor);
			return write(200,result.getString("msg"),"data",result.getString("status"));
		}catch (Exception e){
			e.printStackTrace();
			return error(-1,"查询失败");
		}
	}

	/**
	 * 名医咨询剩余次数查询
	 *
	 * @param doctor
	 * @return
	 */
	@RequestMapping(value = "/consult_times_remain")
	@ResponseBody
	public String famousDoctorTimesRemain(String doctor){
		try{
			int result = doctorWorkTimeService.getDoctorConsultTimesRemain(doctor);
			return write(200,"查询成功","data",result);
		}catch (Exception e){
			e.printStackTrace();
			return error(-1,"查询失败");
		}
	}

	/**
	 * 获取未完成咨询
	 *
	 * @return
	 */
	@RequestMapping(value = "/unfinished")
	@ResponseBody
	public String getUnFinishedConsult(){
		try{
            List<ConsultTeam> unfinishedConsult = consultTeamService.getUnfinishedConsult(getUID());
			JSONArray result = new JSONArray(unfinishedConsult);
            return write(200,"查询成功!","data",result);
		}catch (Exception e){
			e.printStackTrace();
			return error(-1,"查询失败!");
		}
	}

	/**
	 * 三师咨询添加接口
	 * @param type 咨询类型：1三师咨询，2家庭医生咨询
	 * @param when 发病时间
	 * @param symptoms 主要症状
	 * @param images 图片URL地址，多图以逗号分隔
	 * @param voice 语音URL地址
	 * @return
	 */
	@RequestMapping(value = "add")
	@ResponseBody
	public String add(@RequestParam(required = false) Integer type,
					  String when,
					  String symptoms,
					  @RequestParam(required = false) String images,
					  @RequestParam(required = false) String voice) {
		try {
			if (type == null) {
				type = 1;
			}
			if (type != 1 && type != 2) {
				return error(-1, "无效请求！");
			}
			if (consultTeamService.exist(getUID(),type)) {
				return error(-1, "还有咨询未结束，不允许再次提交咨询！");
			}
			if (StringUtils.isEmpty(images)) {
				images = fetchWxImages();
			}
			// 将临时图片拷贝到正式存储路径下
			if (StringUtils.isNotEmpty(images)) {
				images = CommonUtil.copyTempImage(images);
			}
			if (StringUtils.isEmpty(voice)) {
				voice = fetchWxVoices();
			}
			if (StringUtils.isNotEmpty(voice)) {
				voice = CommonUtil.copyTempVoice(voice);
			}
			ConsultTeam consult = new ConsultTeam();
			// 设置咨询类型：1三师咨询，2家庭医生咨询  6.名医咨询
			consult.setType(type);
			// 设置发病时间
			consult.setWhen(when);
			// 设置主要症状
			consult.setSymptoms(symptoms);
			// 设置咨询图片URL
			consult.setImages(images);
			// 设置咨询语音URL
			consult.setVoice(voice);
			// 保存到数据库
			int res = consultTeamService.addTeamConsult(consult, getUID());
			if (res == -1) {
				return error(-1, "家庭签约信息不存在或已过期，无法进行家庭医生咨询！");
			} else if (res == -2) {
				return error(-1, "家庭签约信息不存在或已过期，无法进行三师医生咨询！");
			}

			Doctor doctor = doctorService.findDoctorByCode(consult.getDoctor());
			//创建咨询讨论组
			talkGroupService.createConsultTalkGroup(consult.getDoctor(), doctor.getName(), doctor.getHospital(), doctor.getHosptialName(),
					consult.getPatient(), consult.getName(),consult.getConsult());

			// 添加到统计队列
			if (consult.getType() == 2) {
				DoctorStatisticsTask.getInstance(doctorStatisticsService).put(consult.getDoctor(), 1, 1, 0);
			}
			// 推送消息给医生
			PushMsgTask.getInstance().put(consult.getDoctor(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM.D_CT_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM.指定咨询.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_CONSULT_TEAM.您有新的指定咨询.name(), consult.getConsult());

			return success("提交成功");
		} catch (Exception ex) {
			error(ex);
			return invalidUserException(ex, -1, "提交失败！");
		}
	}

	/**
	 * 名医咨询添加接口
	 * @param when 发病时间
	 * @param symptoms 主要症状
	 * @param images 图片URL地址，多图以逗号分隔
	 * @param voice 语音URL地址
	 * @param doctorCode 名医的code
	 * @return
	 */
	@RequestMapping(value = "famousAdd")
	@ResponseBody
	public String famousAdd(
					  @RequestParam(required = false)String when,
					  String symptoms,
					  @RequestParam(required = false) String doctorCode,
					  @RequestParam(required = false) String images,
					  @RequestParam(required = false) String voice) {
		try {
			//判断医生是否是在工作时间
			JSONObject jo=doctorWorkTimeService.isFamousDoctorWorking(doctorCode);
			if(!jo.get("status").equals("1")){
				return error(-1, jo.get("msg").toString());
			}
			//判断医生是否剩下咨询次数
			int result = doctorWorkTimeService.getDoctorConsultTimesRemain(doctorCode);
			if(result==0){
				return error(-1, "没有次数");
			}
			if (StringUtils.isEmpty(images)) {
				images = fetchWxImages();
			}
			// 将临时图片拷贝到正式存储路径下
			if (StringUtils.isNotEmpty(images)) {
				images = CommonUtil.copyTempImage(images);
			}
			if (StringUtils.isEmpty(voice)) {
				voice = fetchWxVoices();
			}
			if (StringUtils.isNotEmpty(voice)) {
				voice = CommonUtil.copyTempVoice(voice);
			}
			//判断是否已经存在还没有关闭的名医咨询
			if(consultTeamService.isExistFamousConsult(getUID())){
				return error(-1, "已经存在名医咨询！");
			}
			ConsultTeam consult = new ConsultTeam();
			// 设置咨询类型：1三师咨询，2家庭医生咨询 6.名医咨询
			consult.setType(6);
			// 设置发病时间
			consult.setWhen(when);
			// 设置主要症状
			consult.setSymptoms(symptoms);
			// 设置咨询图片URL
			consult.setImages(images);
			// 设置咨询语音URL
			consult.setVoice(voice);
			consult.setDoctor(doctorCode);//设置专科医生
			// 保存到数据库
			consultTeamService.addFamousTeamConsult(consult, getUID());
			//名医咨询次数减一
			doctorWorkTimeService.setDoctorCurrentConsultTimesRemain(doctorCode);
			// 推送消息给医生
			PushMsgTask.getInstance().put(consult.getDoctor(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_FAMOUS_CONSULT_TEAM.D_CT_01.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_FAMOUS_CONSULT_TEAM.名医咨询.name(), MessageType.MESSAGE_TYPE_DOCTOR_NEW_FAMOUS_CONSULT_TEAM.您有新的名医咨询.name(), consult.getConsult());
			return success("提交成功");
		} catch (Exception ex) {
			error(ex);
			return invalidUserException(ex, -1, "提交失败！");
		}
	}

	/**
	 * 名医列表
	 * @return
     */
	@RequestMapping(value = "famousDoctorList")
	@ResponseBody
	public String famousDoctorList(
									@RequestParam(required = false) String name,
									int page,
									int pagesize) {
		try {
			JSONArray array = new JSONArray();
			Page<Doctor>list = doctorService.famousDoctorList(name, page, pagesize);
			if (list != null) {
				for (Doctor doctor : list) {
					if (doctor == null) {
						continue;
					}

					// 判断名医是否在工作
					JSONObject isWorking = doctorWorkTimeService.isFamousDoctorWorking(doctor.getCode());

					if(isWorking == null || !isWorking.getString("status").equals("1")){
						continue;
					}

					JSONObject json = new JSONObject();
					json.put("id", doctor.getId());
					// 医生标识
					json.put("code", doctor.getCode());
					// 医生性别
					json.put("sex", doctor.getSex());
					// 医生姓名
					json.put("name", doctor.getName());
					// 所在医院名称
					json.put("hospital", doctor.getHospital());
					// 所在医院名称
					json.put("hospital_name", doctor.getHosptialName());
					// 科室名称
					json.put("dept_name", (doctor.getDeptName() == null ||
							StringUtils.isEmpty(doctor.getDeptName().toString())) ? " " : doctor.getDeptName());
					// 职称名称
					json.put("job_name", (doctor.getJobName() == null ||
							StringUtils.isEmpty(doctor.getJobName().toString())) ? " " : doctor.getJobName());
					// 头像
					json.put("photo", doctor.getPhoto());
					// 简介
					json.put("introduce", doctor.getIntroduce());
					// 专长
					json.put("expertise", doctor.getExpertise());
					// 剩余咨询次数
					json.put("num", doctorWorkTimeService.getDoctorConsultTimesRemain(doctor.getCode()));
					array.put(json);
				}
			}
			return write(200, "获取医院医生列表成功！", "list", array);
		} catch (Exception e) {
			error(e);
			return error(-1, "获取医院医生列表失败！");
		}
	}

	@RequestMapping(value = "status")
	@ResponseBody
	public String status(String consult) {
		try {
			ConsultTeam ct = consultTeamService.findByCode(consult);
			if (ct == null) {
				return error(-1, "获取状态失败！");
			} else {
				return write(200, "获取状态成功！", "data", ct.getStatus());
			}
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "获取状态失败！");
		}
	}

	/**
	 * 查询患者三师咨询咨询列表
	 * @param status  咨询状态（0未结束，1已结束，-1 已取消）
	 * @param pagesize 页数
	 * @return 查询结果
	 */
	@RequestMapping(value = "list")
	@ResponseBody
	public String list(int status, long id, int pagesize) {
		try {
			Page<ConsultTeam> consults = consultTeamService.findByPatient(getUID(), status, id, pagesize);
			JSONArray jsonArray = new JSONArray();
			if (consults != null) {
				for (ConsultTeam consult : consults) {
					if (consult == null) {
						continue;
					}
					JSONObject json = new JSONObject();
					json.put("id", consult.getId());
					// 设置咨询标志
					json.put("code", consult.getConsult());
					// 设置咨询类型：0公共咨询，1指定医生，2三师咨询
					json.put("type", consult.getType());
					// 设置标题
					json.put("title", consult.getSymptoms());
					// 设置发病时间
					json.put("when", consult.getWhen());
					// 设置患者未读数量
					json.put("patientRead", consult.getPatientRead());
					// 设置状态
					json.put("status", consult.getStatus());
					// 设置患者评价标识
					json.put("comment", consult.getComment());
					// 设置咨询或回复时间
					json.put("time", DateUtil.dateToStr(consult.getCzrq(), DateUtil.YYYY_MM_DD_HH_MM_SS));
					jsonArray.put(json);
				}
			}
			return write(200, "查询成功", "list", jsonArray);
		} catch (Exception ex) {
			error(ex);
			return invalidUserException(ex, -1, "查询失败！");
		}
	}

	/**
	 * 患者取消三师咨询
	 * @param consult
	 * @return
	 */
	@RequestMapping(value = "cancel")
	@ResponseBody
	public String cancel(String consult) {
		try {
			int row = consultTeamService.cancel(consult);
			if (row > 0) {
				return success("咨询已取消！");
			} else {
				return error(-1, "咨询不能取消！");
			}
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "操作失败！");
		}
	}

	/**
	 * 修改状态为1的咨询记录为结束
	 * @param code 咨询标识
	 * @return
	 */
	@RequestMapping(value = "finish")
	@ResponseBody
	public String finish(String code) {
		try {
			int row = consultTeamService.finish(code);
			if (row > 0) {
				return success("操作成功！");
			} else {
				return error(-1, "操作失败！");
			}
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "操作失败！");
		}
	}

	/**
	 * 三师咨询追问接口
	 * @param consult 咨询标识
	 * @param content 追问内容
	 * @param type 追问内容类型：1文字，2图片，3语音
	 * @return
	 */
	@RequestMapping(value = "append")
	@ResponseBody
	public String append(String consult, String content, int type) {
		try {
			List<ConsultTeamLog> logs = new ArrayList<ConsultTeamLog>();
			if (type == 2) {
				// 图片消息
				if (StringUtils.isEmpty(content)) {
					content = fetchWxImages();
				}
				// 将临时图片拷贝到正式存储路径下
				if (StringUtils.isNotEmpty(content)) {
					content = CommonUtil.copyTempImage(content);
				}
				if (StringUtils.isEmpty(content)) {
					return error(-1, "图片上传失败！");
				}
				String[] images = content.split(",");
				for (String image : images) {
					ConsultTeamLog log = new ConsultTeamLog();
					log.setConsult(consult);
					log.setContent(image);
					log.setDel("1");
					log.setChatType(type);
					log.setType(2);
					logs.add(log);
				}
			} else {
				ConsultTeamLog log = new ConsultTeamLog();
				log.setConsult(consult);
				log.setContent(content);
				log.setDel("1");
				log.setChatType(type);
				log.setType(2);
				logs.add(log);
			}
			consultTeamService.reply(logs, getUID());
			return write(200, "追问成功！", "data", content);
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "追问失败！");
		}
	}

	/**
	 * 网络咨询咨询日志查询
	 * @param consult 咨询标识
	 * @param pagesize 每页显示数，默认为10
	 * @return
	 */
	@RequestMapping(value = "loglist")
	@ResponseBody
	public String loglist(String consult, long id, int pagesize) {
		try {
			ConsultTeam consultModel = consultTeamService.findByCode(consult);
			if (consultModel == null) {
				return error(-1, "咨询记录不存在！");
			}
			if (id <= 0) {
				// 更新患者未读数量为0
				consultTeamService.clearPatientRead(consult);
			}
			// 查询日志列表
			JSONArray jsonArray = new JSONArray();
			Page<ConsultTeamLog> list = consultTeamService.findLogByConsult(consult, id, pagesize);
			if (list != null) {
				for (ConsultTeamLog log : list) {
					if (consult == null) {
						continue;
					}
					JSONObject json = new JSONObject();
					json.put("id", log.getId());
					// 设置回复医生姓名
					json.put("doctorName", log.getDoctorName());
					// 设置回复内容
					json.put("content", log.getContent());
					// 设置咨询或回复时间
					json.put("time", DateUtil.dateToStr(log.getCzrq(), DateUtil.YYYY_MM_DD_HH_MM_SS));
					// 设置记录类型：1文字，2图片，3语音
					json.put("msgType", log.getChatType());
					// 设置类型：0患者问，1医生回复，2患者追问，3患者评价
					json.put("type", log.getType());
					jsonArray.put(json);
				}
			}
			// 返回结果
			return write(200, "查询成功", "list", jsonArray);
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "查询失败！");
		}
	}

	/**
	 * 查找单个咨询记录
	 * @param consult 咨询标识
	 * @param logId 记录标识
	 *
	 * @return
	 */
	@RequestMapping(value = "oneLog")
	@ResponseBody
	public String oneLog(String consult,Long logId) {
		try {
			ConsultTeam consultModel = consultTeamService.findByCode(consult);
			if (consultModel == null) {
				return error(-1, "咨询记录不存在！");
			}
			// 查询日志列表
			JSONObject json = new JSONObject();
			ConsultTeamLog log = consultTeamService.oneLog(logId);
			if (log != null) {
					json.put("id", log.getId());
					// 设置回复医生姓名
					json.put("doctorName", log.getDoctorName());
					// 设置回复内容
					json.put("content", log.getContent());
					// 设置咨询或回复时间
					json.put("time", DateUtil.dateToStr(log.getCzrq(), DateUtil.YYYY_MM_DD_HH_MM_SS));
					// 设置记录类型：1文字，2图片，3语音
					json.put("msgType", log.getChatType());
					// 设置类型：0患者问，1医生回复，2患者追问，3患者评价
					json.put("type", log.getType());
			}
			// 返回结果
			return write(200, "查询成功", "consult", json);
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "查询失败！");
		}
	}

	/**
	 * 三师咨询评论
	 * @param consult 咨询标识
	 * @param content 评价内容
	 * @param star 星级
	 * @return 操作结果
	 */
	@RequestMapping(value = "comment")
	@ResponseBody
	public String comment(String consult, String content, int star) {
		try {
			// 保存评价
			JSONArray array = doctorCommentService.consultComment(getUID(), consult, content, star, 2);
			// 添加到统计队列
			if (array != null) {
				DoctorStatisticsTask.getInstance(doctorStatisticsService).put(array);
			}
			// 添加评价记录
			ConsultTeamLog log = new ConsultTeamLog();
			log.setConsult(consult);
			log.setContent(content);
			log.setChatType(1);
			log.setDel("1");
			log.setType(3);
			log = consultTeamService.reply(log, getUID(), null, log.getType());
			return success("感谢您的评价！");
		} catch (Exception e) {
			error(e);
			return invalidUserException(e, -1, "评价失败！");
		}

	}
}
