package com.yihu.wlyy.service.app.followup;

import javax.transaction.Transactional;

import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.wlyy.entity.dict.SystemDict;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.followup.Followup;
import com.yihu.wlyy.entity.followup.FollowupContent;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.repository.dict.SystemDictDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.followup.FollowupContentDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.service.system.SystemDictService;
import com.yihu.wlyy.task.FollowupUploadTask;
import com.yihu.wlyy.util.DateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Component;

import com.yihu.wlyy.repository.followup.FollowUpDao;
import com.yihu.wlyy.service.BaseService;

import java.util.*;

/**
 * 随访服务
 * @author hzp add 2016-12-07
 *
 */
@Component
@Transactional(rollbackOn = Exception.class)
public class FollowUpService extends BaseService {

	@Autowired
	private DoctorDao doctorDao;

	@Autowired
	private PatientDao patientDao;

	@Autowired
	private FollowUpDao followupDao;

	@Autowired
	private FollowupContentDao followupContentDao;

	@Autowired
	private SystemDictService systemDictService;

	@Autowired
	private ObjectMapper objectMapper;

	/**
	 * 转译随访信息
     */
	private Map<String,String> getFollowupDetail(Followup followup) throws Exception
	{
		Map<String,String> re = new HashMap<>();
		//患者信息
		String patientCode = followup.getPatientCode();
		Patient patient = patientDao.findByCode(patientCode);
		if(patient!=null) {
			re.put("patientCode",patientCode);
			re.put("patientName",patient.getName());
			re.put("idcard",patient.getIdcard());
			re.put("sex",String.valueOf(patient.getSex()));
			re.put("birthday",DateUtil.dateToStrLong(patient.getBirthday()));

		}
		else{
			throw new Exception("not exit patient:"+patientCode);
		}

		re.put("id",String.valueOf(followup.getId()));
		re.put("followupNo",followup.getFollowupNo());
		re.put("followupDate",DateUtil.dateToStrLong(followup.getFollowupDate()));
		re.put("followupNextDate",DateUtil.dateToStrLong(followup.getFollowupNextDate()));

		//随访方式转译
		re.put("followupType",followup.getFollowupType());
		String followupTypeName = systemDictService.getDictValue("FOLLOWUP_WAY_DICT",followup.getFollowupType());
		re.put("followupTypeName",followupTypeName);

		//随访类别转译
		re.put("followupClass",followup.getFollowupClass());
		String followupClassName = systemDictService.getDictValue("FOLLOWUP_CLASS_DICT",followup.getFollowupClass());
		re.put("followupClassName",followupClassName);

		//随访管理状态转译
		re.put("followupManagerStatus",followup.getFollowupManagerStatus());
		String followupManagerStatusName = systemDictService.getDictValue("FOLLOWUP_MANAGER_STATUS",followup.getFollowupManagerStatus());
		re.put("followupManagerStatusName",followupManagerStatusName);

		re.put("doctorCode",followup.getDoctorCode());
		re.put("doctorName",followup.getDoctorName());
		re.put("orgCode",followup.getOrgCode());
		re.put("orgName",followup.getOrgName());
		re.put("dataFrom",followup.getDataFrom());
		re.put("status",followup.getStatus());
		re.put("followupContentPhone",followup.getFollowupContentPhone());
		re.put("createTime",DateUtil.dateToStrLong(followup.getCreateTime()));
		re.put("creater",followup.getCreater());

		return re;
	}

	/**
	 * 获取医生随访列表
     */
	public List<Map<String,String>> getListByDoctor(String doctorCode,String startTime,String endTime,String page,String pageSize) throws Exception
	{
		List<Map<String,String>> re = new ArrayList<>();
		// 排序
		Sort sort = new Sort(Sort.Direction.ASC, "followupDate");
		// 分页信息
		int pageInt = Integer.valueOf(page)-1;
		int pageSizeInt =  Integer.valueOf(pageSize);
		Pageable pageRequest = new PageRequest(pageInt, pageSizeInt, sort);
		List<Followup> list = followupDao.findByDoctor(doctorCode,DateUtil.strToDate(startTime),DateUtil.strToDate(endTime),pageRequest);

		if(list!=null && list.size()>0)
		{
		    for(Followup followup : list)
			{
				Map<String,String> map = getFollowupDetail(followup);
				re.add(map);
			}
		}

		return re;
	}

	/**
	 * 获取医生随访列表(创建者)
	 */
	public List<Map<String,String>> getListByCreater(String doctorCode,String startTime,String endTime,String page,String pageSize) throws Exception
	{
		List<Map<String,String>> re = new ArrayList<>();
		// 排序
		Sort sort = new Sort(Sort.Direction.ASC, "followupDate");
		// 分页信息
		int pageInt = Integer.valueOf(page)-1;
		int pageSizeInt =  Integer.valueOf(pageSize);
		Pageable pageRequest = new PageRequest(pageInt, pageSizeInt, sort);
		List<Followup> list = followupDao.findByCreater(doctorCode,DateUtil.strToDate(startTime),DateUtil.strToDate(endTime),pageRequest);

		if(list!=null && list.size()>0)
		{
			for(Followup followup : list)
			{
				Map<String,String> map = getFollowupDetail(followup);
				re.add(map);
			}
		}

		return re;
	}

	/**
	 *新增随访计划（批量）
	 */
	@Transactional
	public void addFollowupPlan(String doctorCode,String patientCode,String data) throws Exception {
		//批量随访计划
		JavaType javaType = objectMapper.getTypeFactory().constructParametricType(List.class, Map.class);
		List<Map<String,String>> list = objectMapper.readValue(data,javaType);
		if(list!=null && list.size()>0)
		{
			//获取患者信息
			Patient patient = patientDao.findByCode(patientCode);
			if(patient==null)
			{
				throw new Exception("not exit patient:"+patientCode+".\r\n");
			}

			List<Followup> followupPlan = new ArrayList<>();
			for(Map<String,String> map : list)
			{
				//获取医生信息
				Doctor doctor = doctorDao.findByCode(map.get("doctor"));
				if(doctor==null)
				{
					throw new Exception("not exit doctor:"+doctorCode+".\r\n");
				}

				Followup followup = new Followup();
				followup.setFollowupType(map.get("type"));
				followup.setFollowupDate(DateUtil.strToDate(map.get("date")));
				followup.setDoctorCode(doctor.getCode());
				followup.setDoctorName(doctor.getName());
				followup.setOrgCode(doctor.getHospital());
				followup.setOrgName(doctor.getHospitalName());
				followup.setPatientCode(patientCode);
				followup.setPatientName(patient.getName());
				followup.setIdcard(patient.getIdcard());
				followup.setDataFrom("2");//数据来源 1基卫 2APP
				followup.setStatus("2");     //状态 0取消 1已完成 2未开始 3进行中
				followup.setCreateTime(new Date());
				followup.setCreater(doctorCode);

				followupPlan.add(followup);
			}

			followupDao.save(followupPlan);
		}
	}

	/**
	 *开始随访记录
	 */
	public void startFollowup(String id,String date,String followupType,String followupClass,String followupManagerStatus) throws Exception {
		 Followup followup = followupDao.findOne(Long.valueOf(id));
		 if(followup!=null)
		 {
			 followup.setFollowupDate(DateUtil.strToDate(date));
			 followup.setFollowupType(followupType);
			 followup.setFollowupClass(followupClass);
			 followup.setFollowupManagerStatus(followupManagerStatus);
			 followup.setStatus("3");  //状态 0取消 1已完成 2未开始 3进行中

			 followupDao.save(followup);
		 }
		else{
			 throw new Exception("not exit follow:"+id+".\r\n");
		 }
	}

	/**
	 *新增临时随访记录（返回ID）
	 */
	public String addFollowup(String doctorCode,String patientCode,String date,String followupType,String followupClass,String followupManagerStatus) throws Exception {
		String re ="";

		//获取医生信息
		Doctor doctor = doctorDao.findByCode(doctorCode);
		if(doctor==null)
		{
			throw new Exception("not exit doctor:"+doctorCode+".\r\n");
		}

		//获取患者信息
		Patient patient = patientDao.findByCode(patientCode);
		if(patient==null)
		{
			throw new Exception("not exit patient:"+patientCode+".\r\n");
		}

		Followup followup = new Followup();
		followup.setFollowupDate(DateUtil.strToDate(date));
		followup.setDoctorCode(doctorCode);
		followup.setDoctorName(doctor.getName());
		followup.setOrgCode(doctor.getHospital());
		followup.setOrgName(doctor.getHospitalName());
		followup.setPatientCode(patientCode);
		followup.setPatientName(patient.getName());
		followup.setIdcard(patient.getIdcard());
		followup.setFollowupType(followupType);
		followup.setFollowupClass(followupClass);
		followup.setFollowupManagerStatus(followupManagerStatus);
		followup.setDataFrom("2");//数据来源 1基卫 2APP
		followup.setStatus("3");     //状态 0取消 1已完成 2未开始 3进行中
		followup.setCreateTime(new Date());
		followup.setCreater(doctorCode);

		followupDao.save(followup);
		re = String.valueOf(followup.getId());
		return re;
	}

	/**
	 *取消随访计划
	 */
	public void cancelFollowupPlan(String id) throws Exception {
		Followup followup = followupDao.findOne(Long.valueOf(id));
		if(followup!=null)
		{
			followup.setStatus("0");  //状态 0取消 1已完成 2未开始 3进行中
			followupDao.save(followup);
		}
		else{
			throw new Exception("not exit follow:"+id+".\r\n");
		}
	}

	/**
	 * 完成随访记录，并上传随访记录
     */
	public void finishFollowup(String id) throws Exception {
		Followup followup = followupDao.findOne(Long.valueOf(id));
		if(followup!=null)
		{
			followup.setStatus("1");  //状态 0取消 1已完成 2未开始 3进行中
			followupDao.save(followup);

			//上传随访计划
			new Thread(new FollowupUploadTask(String.valueOf(followup.getId()))).start();
		}
		else{
			throw new Exception("not exit follow:"+id+".\r\n");
		}
	}

	/*********************************** 随访详情 *******************************************************************/
	/**
	 * 获取面访项目列表
	 */
	public Map<String,String> getFollowup(String id) throws Exception
	{
		Map<String,String> re = new HashMap<>();
		Followup followup = followupDao.findOne(Long.valueOf(id));
		if(followup!=null)
		{
			re = getFollowupDetail(followup);
		}
		else{
			throw new Exception("not exit follow:"+id+".\r\n");
		}
		return re;
	}

	/**
	 * 获取面访项目列表
	 */
	public List<Map<String,String>> getFollowupProject(String id) throws Exception
	{
		List<Map<String,String>> re = new ArrayList<>();
		//获取已填写的面访项目
		List<String> project = followupContentDao.findProjectByFollowupId(Long.valueOf(id));
		//获取所有面访项目
		List<SystemDict> dictList = systemDictService.getDictByDictName("FOLLOWUP_PROJECT");
		if (dictList!=null && dictList.size()>0)
		{
			for(SystemDict dict:dictList)
			{
				Map<String,String> map = new HashMap<>();
				String code = dict.getCode();
				map.put("projectCode",code);
				map.put("projectName",dict.getValue());
				if(project!=null && project.contains(code))
				{
					map.put("status","1"); //已填写
				}
				else{
					map.put("status","0");//未填写
				}
				re.add(map);
			}
		}
		return re;
	}

	/**
	 * 获取面访项目数据
	 */
	public Map<String,String> getFollowupProjectData(String id,String followupProject) throws Exception
	{
		Map<String,String> re = new HashMap<>();
		List<FollowupContent> dataList =  followupContentDao.findByFollowupIdAndFollowupProject(Long.valueOf(id),followupProject);
		for(FollowupContent item:dataList)
		{
			re.put(item.getFollowupKey(),item.getFollowupValue());
		}
		return re;
	}

	/**
	 *保存面访项目数据
	 */
	@Transactional
	public void saveFollowupProjectData(String id,String followupProject,String followupProjectData) throws Exception {
		List<FollowupContent> dataList = followupContentDao.findByFollowupIdAndFollowupProject(Long.valueOf(id),followupProject);

		//删除原有记录
		followupContentDao.delete(dataList);

		Map<String,String> data =  objectMapper.readValue(followupProjectData,Map.class);

		if(data!=null && data.keySet().size()>0)
		{
			List<FollowupContent> newList = new ArrayList<>();
			for (String key : data.keySet()) {
				FollowupContent item = new FollowupContent();
				item.setFollowupId(Long.valueOf(id));
				item.setFollowupProject(followupProject);
				item.setFollowupKey(key);
				item.setFollowupValue(data.get(key));
				item.setCreateTime(new Date());
				newList.add(item);
			}
			followupContentDao.save(newList);

		}
	}



	/*********************************** 电话随访 *****************************************************************/
	/**
	 *获取电话随访内容
	 */
	public String getFollowupPhone(String id) throws Exception {
		String re = "";
		Followup followup = followupDao.findOne(Long.valueOf(id));
		if(followup!=null)
		{
			re = followup.getFollowupContentPhone();
		}
		else {
			throw new Exception("not exit followup:"+id+".\r\n");
		}
		return re;
	}

	/**
	 *记录电话随访内容
	 */
	public void saveFollowupPhone(String id,String content) throws Exception {
		Followup followup = followupDao.findOne(Long.valueOf(id));
		if(followup!=null)
		{
			followup.setFollowupContentPhone(content);
			followupDao.save(followup);
		}
		else {
			throw new Exception("not exit followup:"+id+".\r\n");
		}
	}


}
