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

import java.util.*;

import javax.transaction.Transactional;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.service.third.guahao.GuahaoXMService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Component;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.patient.PatientReservation;
import com.yihu.wlyy.entity.patient.PatientReservationDoctor;
import com.yihu.wlyy.repository.patient.PatientReservationDao;
import com.yihu.wlyy.repository.patient.PatientReservationDoctorDao;
import com.yihu.wlyy.service.BaseService;

/**
 * 预约挂号业务处理类
 * @author George
 *
 */
@Component
@Transactional(rollbackOn = Exception.class)
public class PatientReservationService extends BaseService {

	@Autowired
	private PatientReservationDao patientReservationDao;
	@Autowired
	private PatientReservationDoctorDao patientReservationDoctorDao;

	@Autowired
	private GuahaoXMService  guahaoXMService;

	@Autowired
	private ObjectMapper objectMapper;

	@Autowired
	private PatientDao patientDao;

	public PatientReservation findByCode(String code){
		return patientReservationDao.findByCode(code);
	}

	public PatientReservation findById(Long id) throws Exception{
		PatientReservation re = patientReservationDao.findById(id);

		if(re==null)
		{
			throw new Exception("not exit result!id:"+id);
		}

		return re;
	}


	/**
	 * 实体转map
	 */
	private Map<String, String> entityToMap(PatientReservation obj) throws Exception {
		String mapString = objectMapper.writeValueAsString(obj);
		return objectMapper.readValue(mapString, Map.class);
	}

	/**
	 * 更新预约状态
     */
	@Transactional
	public void updateStatus(Long id,Integer status)
	{
		PatientReservation obj=  patientReservationDao.findOne(id);
		if(!obj.getStatus().equals(status))
		{
			obj.setStatus(status);
			patientReservationDao.save(obj);
		}
	}

	/**
	 * 保存预约挂号记录
	 * @param code 预约号/流水号
	 * @param doctor 医生标识
	 * @param patient 患者标识
	 * @param idcard 患者身份证号
	 * @param name 患者姓名
	 * @param phone 患者手机号
	 * @param ssc 患者社保卡号
	 * @param section_type 预约时间段：AM (上午)或者PM (下午)
	 * @param start_time 一次预约段的开始时间
	 * @param org_code 医生所在医疗机构编码
	 * @param org_name 医疗机构名称
	 * @param dept_code 科室编码
	 * @param dept_name 科室名称
	 * @param doctor_code 专家ID/编码
	 * @param doctor_name 专家姓名
	 * @param doctor_photo 专家头像
	 * @return
	 */
	public void save(String code, Doctor doctor, String patient, String idcard, String name, String phone, String ssc, String section_type, String start_time, String org_code, String org_name, String dept_code, String dept_name, String doctor_code, String doctor_name, String doctor_job, String doctor_photo) {
		try {
			PatientReservation reservation = new PatientReservation();
			reservation.setCode(code);
			reservation.setCzrq(new Date());
			reservation.setType("1");
			reservation.setDeptCode(dept_code);
			reservation.setDeptName(dept_name);
			if (doctor != null) {
				reservation.setDname(doctor.getName());
				reservation.setDoctor(doctor.getCode());
			}
			reservation.setDoctorCode(doctor_code);
			reservation.setDoctorName(doctor_name);
			reservation.setDoctorJob(doctor_job);
			reservation.setDoctorPhoto(doctor_photo);
			reservation.setIdcard(idcard);
			reservation.setName(doctor_name);
			reservation.setOrgCode(org_code);
			reservation.setOrgName(org_name);
			reservation.setPatient(patient);
			reservation.setPhone(phone);
			reservation.setSectionType(section_type);
			reservation.setSsc(ssc);
			reservation.setStartTime(start_time);
			reservation.setStatus(1);
			// 保存记录
			PatientReservation temp = patientReservationDao.save(reservation);
			if (temp != null) {
				// 先删除，防止重复
				patientReservationDoctorDao.deleteByPatient(patient, org_code, dept_code, doctor_code);
				// 添加预约过的医生
				PatientReservationDoctor prd = new PatientReservationDoctor();
				prd.setDeptCode(dept_code);
				prd.setDeptName(dept_name);
				prd.setDoctorCode(doctor_code);
				prd.setDoctorName(doctor_name);
				prd.setOrgCode(org_code);
				prd.setOrgName(org_name);
				prd.setPatient(patient);
				patientReservationDoctorDao.save(prd);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	/**
	 * 查询患者预约过的医生列表
	 * @param patient
	 * @return
	 */
	public Page<PatientReservationDoctor> findRecordByPatient(String patient, long id, int pagesize) {
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(0, pagesize, sort);

		// 设置查询条件
		Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
		// 未指定医生
		filters.put("patient", new SearchFilter("patient", Operator.EQ, patient));
		if (id > 0) {
			filters.put("id", new SearchFilter("id", Operator.LT, id));
		}
		Specification<PatientReservationDoctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), PatientReservationDoctor.class);
		return patientReservationDoctorDao.findAll(spec, pageRequest);
	}

	/**
	 * 分页获取患者预约记录,医生为空查患者所有
     */
	@Transactional
	public List<PatientReservation> getReservationByPatient(String patient,Long teamCode, int page, int pagesize) throws Exception
	{
		List<PatientReservation> list = new ArrayList<>();
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(page-1, pagesize, sort);
		if(teamCode == null || teamCode < 1){//传入医生查询医生帮此患者的预约记录
			list = patientReservationDao.findByPatientAndAdminTeamCode(patient, teamCode, pageRequest);
		}else{
			list = patientReservationDao.findByPatient(patient, pageRequest);
		}

		//更新当前状态
		if(list!=null)
		{
			//遍历更新预约状态
			for (PatientReservation item : list) {
				String type = item.getType();
				String code = item.getCode();
				if (type.equals("0")) {  //医护网接口

				}
				else if (type.equals("1"))   //厦门市民健康预约接口
				{
					Integer status = guahaoXMService.GetOrderStatus(item.getOrgCode(), code, item.getSsc());
					//更新状态
					if (status != null && !status.equals(item.getStatus())) {
						item.setStatus(status);
					}
				}
			}

			patientReservationDao.save(list);
		}

		return list;
	}


	/**
	 * 分页获取患者预约记录（医生端）
	 */
	public List<Map<String,String>> getReservationByDoctor(String doctor, int page, int pagesize) throws Exception
	{
		List<Map<String,String>> re = new ArrayList<>();
		// 排序
		Sort sort = new Sort(Direction.DESC, "id");
		// 分页信息
		PageRequest pageRequest = new PageRequest(page-1, pagesize, sort);
		List<PatientReservation> list = patientReservationDao.findByDoctor(doctor, pageRequest);

		//更新当前状态
		if(list!=null)
		{
			//遍历更新预约状态
			for (PatientReservation item : list) {
				String type = item.getType();
				String code = item.getCode();
				if (type.equals("0")) {  //医护网接口

				}
				else if (type.equals("1"))   //厦门市民健康预约接口
				{
					Integer status = guahaoXMService.GetOrderStatus(item.getOrgCode(), code, item.getSsc());
					//更新状态
					if (status != null && !status.equals(item.getStatus())) {
						item.setStatus(status);
					}
				}
			}
			patientReservationDao.save(list);
		}

		//返回患者头像
		for (PatientReservation item : list) {
			Map<String,String> map = entityToMap(item);

			Patient patient = patientDao.findByCode(item.getPatient());
			if(patient!=null){
				map.put("photo",patient.getPhoto());
			}
			re.add(map);

		}
		return re;
	}

	public Long countReservationByDoctorForPatient(String doctor,String patient){
		return patientReservationDao.countReservationByDoctorForPatient(doctor,patient);
	}
}
