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

import java.util.*;

import com.yihu.wlyy.entity.address.City;
import com.yihu.wlyy.entity.address.Province;
import com.yihu.wlyy.entity.address.Town;
import com.yihu.wlyy.entity.consult.Consult;
import com.yihu.wlyy.entity.consult.ConsultTeam;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorPatientGroup;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorPatientGroupInfo;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorTeam;
import com.yihu.wlyy.entity.doctor.team.sign.DoctorTeamMember;
import com.yihu.wlyy.entity.doctor.OperatorLog;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.entity.patient.WlyyPatientSick;
import com.yihu.wlyy.repository.address.CityDao;
import com.yihu.wlyy.repository.address.ProvinceDao;
import com.yihu.wlyy.repository.address.TownDao;
import com.yihu.wlyy.repository.consult.ConsultDao;
import com.yihu.wlyy.repository.consult.ConsultTeamDao;
import com.yihu.wlyy.repository.consult.ConsultTeamDoctorDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.doctor.DoctorPatientGroupInfoDao;
import com.yihu.wlyy.repository.doctor.DoctorTeamDao;
import com.yihu.wlyy.repository.doctor.DoctorTeamMemberDao;
import com.yihu.wlyy.repository.doctor.OperatorLogDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.PatientSickDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.service.app.scheduling.DoctorWorkTimeService;
import com.yihu.wlyy.service.app.talk.TalkGroupService;
import com.yihu.wlyy.service.common.SMSService;
import com.yihu.wlyy.task.PushMsgTask;
import com.yihu.wlyy.util.DateUtil;
import com.yihu.wlyy.util.MD5;
import com.yihu.wlyy.wechat.util.WeiXinAccessTokenUtils;
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.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.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.yihu.wlyy.service.BaseService;
import com.yihu.wlyy.util.EncodesUtil;

/**
 * 医生基本信息类.
 *
 * @author George
 */
// Spring Service Bean的标识.
@Component
public class DoctorInfoService extends BaseService {

    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private ProvinceDao provinceDao;
    @Autowired
    private CityDao cityDao;
    @Autowired
    private TownDao townDao;
    @Autowired
    private DoctorTeamDao doctorTeamDao;
    @Autowired
    private DoctorTeamMemberDao doctorTeamDoctor;
    @Autowired
    private DoctorPatientGroupInfoDao doctorPatientGroupInfoDao;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private ConsultTeamDoctorDao consultTeamDoctorDao;
    @Autowired
    private PatientSickDao patientSickDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private ConsultDao consultDao;
    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private ConsultTeamDao consultTeamDao;
    @Autowired
    SMSService smsService;
    @Autowired
    DoctorWorkTimeService workTimeService;
    @Autowired
    TalkGroupService talkGroupService;
    @Autowired
    WeiXinAccessTokenUtils accessTokenUtils;
    @Autowired
    protected OperatorLogDao operatorLogDao;

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    @Transactional
    public List<Object> getDoctorSignPatients(String doctor) {
        return signFamilyDao.findDoctorSignPatients(doctor);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    @Transactional
    public List<Object> getDoctorSignPatientsLikeName(String doctor, String patientName) {
        return signFamilyDao.findDoctorSignPatientsLikeName(doctor, patientName);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    @Transactional
    public List<Object> getDoctorSignPatientsBySignType(String doctor, int type) {
        return signFamilyDao.findDoctorSignPatientsBySignType(doctor, type);
    }

    /**
     * 获取医生的签约病人
     *
     * @param doctor
     * @return
     */
    @Transactional
    public List<Object> getDoctorSignPatientsByTypeName(String doctor, int type, String patientName) {
        return signFamilyDao.findDoctorSignPatientsByTypeName(doctor, type, patientName);
    }

    @Transactional
    public Doctor findDoctorByCode(String code) {
        return doctorDao.findByCode(code);
    }

    @Transactional
    public Doctor findDoctorByMobile(String mobile) {
        return doctorDao.findByMobile(mobile);
    }

    /**
     * 获取正常医生
     *
     * @param mobile
     * @return
     */
    @Transactional
    public Doctor findNormalByMobile(String mobile) {
        return doctorDao.findNormalByMobile(mobile);
    }

    /**
     * 更新医生基本信息
     *
     * @param doctor
     * @return
     */
    @Transactional
    public Doctor updateDoctor(Doctor doctor) {
        Province province = provinceDao.findByCode(doctor.getProvince());
        if (province != null) {
            doctor.setProvinceName(province.getName());
        }
        City city = cityDao.findByCode(doctor.getCity());
        if (city != null) {
            doctor.setCityName(city.getName());
        }
        Town town = townDao.findByCode(doctor.getTown());
        if (town != null) {
            doctor.setTownName(town.getName());
        }
        // Hospital hospital = hospitalDao.findByCode(doctor.getHospital());
        // if(hospital != null){
        // doctor.setHosptialName(hospital.getName());
        // }
        // HospitalDept dept = hospitalDeptDao.findByCode(doctor.getDept());
        // if(dept != null){
        // doctor.setDeptName(dept.getName());
        // }
        // JobTitle job = jobDao.findByCode(doctor.getJob());
        // if(job != null){
        // doctor.setJobName(job.getName());
        // }
        return doctorDao.save(doctor);
    }

    /**
     * 修改医生密码
     */
    @Transactional
    public void updateDoctorPwd(Doctor doctor) {
        EncodesUtil.entryptPassword(doctor);
        doctorDao.save(doctor);
    }

    /**
     * 查询指定医生下的患者
     *
     * @param doctor
     * @return
     */
    @Transactional
    public List<Object> findPatientByDoctorSign(String doctor) {
        return doctorDao.findPatientByDoctorSign(doctor);
    }

    @Transactional
    public Page<Object> findPatientByDoctorSign(String doctor, long id,
                                                int pagesize, String patientName) {
        // return doctorDao.findPatientByDoctorSign(doctor);

        Page<Object> signList = null;

        if (pagesize <= 0) {
            pagesize = 10;
        }
        // 分页信息
        PageRequest pageRequest = new PageRequest(0, pagesize);

        if (StringUtils.isEmpty(patientName)) {
            // doctorDao.findPatientByDoctorSign(doctor);
            if (id > 0) {
                signList = doctorDao.findPatientByDoctorSign(doctor, id,
                        pageRequest);

            } else {
                signList = doctorDao.findPatientByDoctorSign(doctor,
                        pageRequest);
            }
        } else {
            patientName = "%" + patientName + "%";
            if (id > 0) {
                signList = doctorDao.findPatientByDoctorSign(doctor, id,
                        patientName, pageRequest);

            } else {
                signList = doctorDao.findPatientByDoctorSign(doctor,
                        patientName, pageRequest);
            }
        }

        return signList;
    }

    /**
     * 查该医生管理的患者总数
     *
     * @param doctor
     * @return
     */
    @Transactional
    public int amountPatientByDoctorSign(String doctor) {
        return doctorDao.amountPatientByDoctorSign(doctor);
    }

    /**
     * 查询指定医生的患者分组
     *
     * @param doctor
     * @return
     */
    @Transactional
    public Iterable<DoctorPatientGroup> findDoctorPatientGroup(String doctor) {
        return doctorDao.findDoctorPatientGroup(doctor);
    }

    @Transactional
    public Patient findPatientByCode(String code) {
        return doctorDao.findPatientByCode(code);
    }

    @Transactional
    public DoctorPatientGroupInfo findGroup(String user, String doctor) {
        return doctorDao.findGroup(user, doctor);
    }

    /**
     * 根据医院信息获取医生列表
     *
     * @param query    查询条件 ：医生名称
     * @param id
     * @param hospital 医院标识
     *                 页数
     * @return
     */
    @Transactional
    public Page<Doctor> getDoctorListByHospital(String query, String hospital,
                                                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>();
        if (StringUtils.isNotEmpty(query)) {
            filters.put("name", new SearchFilter("name", Operator.LIKE, query));
        }
        if (StringUtils.isNotEmpty(hospital)) {
            hospital = hospital.substring(0, 8);
            filters.put("hospital", new SearchFilter("hospital", Operator.LIKE,
                    hospital));
        }
        if (id > 0) {
            filters.put("id", new SearchFilter("id", Operator.LT, id));
        }
        filters.put("level", new SearchFilter("level", Operator.EQ, 2));
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(
                filters.values(), Doctor.class);
        return doctorDao.findAll(spec, pageRequest);
    }

    @Transactional
    public List<Doctor> getDoctorCombobxByHospital(String type, String hospital) {

        return doctorDao.getDoctorCombobxByHospital(hospital, Integer.valueOf(type));
    }

    @Transactional
    public Doctor getDoctor(int consultType, String patientCode) {
        //根据病人ID查找团队
        //DoctorTeam doctorTeam =doctorTeamDao.getBy
        return null;
    }

    @Transactional
    public Page<Doctor> getDoctorListByPatientCode(int consultType, String patientCode, String name, int page, int pageSize) {
        //
        return null;
    }

    @Transactional
    public Page<Doctor> getDoctorListByHospital(String name, String paitentCode, Integer page, Integer pageSize) {
        if (pageSize == null | pageSize <= 0) {
            pageSize = 10;
        }
        if (page == null | page <= 0) {
            page = 1;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "name");
        // 分页信息
        PageRequest pageRequest = new PageRequest(page - 1, pageSize, sort);
        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(name)) {
            filters.put("name", new SearchFilter("name", SearchFilter.Operator.LIKE, name));
        }
        filters.put("status", new SearchFilter("status", SearchFilter.Operator.EQ, 1));
        filters.put("level", new SearchFilter("level", SearchFilter.Operator.EQ, 1));
        filters.put("iscertified", new SearchFilter("iscertified", SearchFilter.Operator.EQ, 1));
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);

        return doctorDao.findAll(spec, pageRequest);
    }

    @Transactional
    public void doctor_1_Toteam(String teamCode, String doctor, String doctorName, String groupCode, String loginCode, String parientCode, String sickName, String sickNCode) {
        //得到患者所在的团队
        DoctorTeam doctorTeam = doctorTeamDao.findByParientCode(parientCode);

        //添加专科医生
        //判断专科医生之前是否已经加入到这个团队
        DoctorTeamMember wlyyDoctorTeamDoctorTemp = doctorTeamDoctor.findMemberCodeAndTeam(doctorTeam.getCode(), doctor);
        if (wlyyDoctorTeamDoctorTemp != null) {

        } else {
            Patient patient = patientDao.findByCode(parientCode);
            patient.setDisease(Integer.valueOf(sickNCode));

            //更新之前这个团队的专业医生的del为0
            doctorTeamDoctor.updateType1Del(doctorTeam.getCode());
            //更新之前的患者病种表的del为0
            patientSickDao.updateType1Del(parientCode, sickNCode);
            // 专科医生没有分组的概念
            DoctorTeamMember wlyyDoctorTeamDoctor = new DoctorTeamMember();
            wlyyDoctorTeamDoctor.setTeam(doctorTeam.getCode());
            wlyyDoctorTeamDoctor.setMemberCode(doctor);
            wlyyDoctorTeamDoctor.setName(doctorName);
            wlyyDoctorTeamDoctor.setDel("1");
            wlyyDoctorTeamDoctor.setType(1);
            wlyyDoctorTeamDoctor.setSignType("2");//家庭签约
            wlyyDoctorTeamDoctor.setCode(getCode());
            wlyyDoctorTeamDoctor.setCzrq(new Date());
            doctorTeamDoctor.save(wlyyDoctorTeamDoctor);

            //添加患者患病表
            WlyyPatientSick wlyyPatientSick = new WlyyPatientSick();
            wlyyPatientSick.setDel("1");//未删除
            wlyyPatientSick.setCzrq(new Date());
            wlyyPatientSick.setCode(getCode());
            wlyyPatientSick.setPatientCode(parientCode);
            wlyyPatientSick.setDoctorCode(doctor);
            wlyyPatientSick.setSickName(sickName);
            wlyyPatientSick.setSickCode(sickNCode);
            wlyyPatientSick.setSignType("2");//家庭签约
            patientSickDao.save(wlyyPatientSick);
        }
        //把患者所在的健康管理师的组转慢病
        //查找出团队的全科医生
        //DoctorTeamMember doctor2= doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(),"2");
        //查找出团队的健康管理师
        //DoctorTeamMember doctor3= doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(),"3");
        //把患者转到的慢病组里
        doctorPatientGroupInfoDao.updateGroupByParient(parientCode);

    }

    @Transactional
    public Doctor getDoctor2ByParient(String parientCode, String consultCode) throws Exception {
        //得到咨询的类别
        Consult consult = consultDao.findByCode(consultCode);
//		//查找病人所在的团队
        DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, "" + consult.getType());
        //得到团队的全科医生
        DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 2);
        //得到全科医生
        Doctor doctor = doctorDao.findByCode(doctorTeamMember.getMemberCode());
        //判断全科医生是否已经加入讨论组
        //ConsultTeamDoctor consultTeamDoctor = consultTeamDoctorDao.getByConsultCodeAndDoctorCode(consultCode, doctor.getCode());
        //判断全科医生是否已经加入讨论组
        JSONObject talkGroup = talkGroupService.findConsultTalkGroup(consultCode);
        if (talkGroup != null) {
            return null;
        }
        return doctor;
    }

    @Transactional
    public List<Map> findNoInConsultDoctor(String existDoc, String consultCode, int page, int pageSzie) {
        int start = (page - 1) * pageSzie;
        String sql = "select p.* from wlyy_doctor p where " +
                "NOT EXISTS (SELECT 1 from wlyy_consult_team_doctor d WHERE d.to_doctor=p.code and d.consult='" + consultCode + "') " +
                " and p.level = 1 and p.iscertified=1 and p.status=1 and p.code<>'" + existDoc + "'" +
                " ORDER BY p.code limit " + start + "," + pageSzie;
        List rs = jdbcTemplate.queryForList(sql);
        return rs;
    }

    @Transactional
    public int countNoInConsultDoctor(String existDoc, String consultCode) {
        String sql = "SELECT count(*) as c FROM (" +
                "select 1 as c from wlyy_doctor p where " +
                "NOT EXISTS (SELECT 1 from wlyy_consult_team_doctor d WHERE d.to_doctor=p.code and d.consult='" + consultCode + "') " +
                " and p.level = 1 and p.iscertified=1 and p.status=1 and p.code<>'" + existDoc + "'" +
                ") b";
        List rs = jdbcTemplate.queryForList(sql);
        return ((Long) ((Map) rs.get(0)).get("c")).intValue();
    }

    @Transactional
    public Map<String, Object> getDoctor1ByParient(String consultCode, String parientCode, Integer page, Integer pageSzie) {
        Map<String, Object> returnMap = new HashMap<>();
        if (pageSzie == null | pageSzie <= 0) {
            pageSzie = 10;
        }
        if (page == null | page <= 0) {
            page = 1;
        }
        Consult consult = consultDao.findByCode(consultCode);
        if (consult.getType() == 2) {
            //查找病人所在的团队
            DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, consult.getType() + "");
            //得到团队的专科医生

            DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 1);
            String existDoc = doctorTeamMember != null ? doctorTeamMember.getMemberCode() : null;
            List<Map> rs = findNoInConsultDoctor(existDoc, consultCode, page, pageSzie);
            Doctor doctor = null;

            List<JSONObject> newDoctors = new ArrayList<>();
            JSONObject json;
            if (page == 1 && doctorTeamMember != null) {
                //如果专科存在
                if (consultTeamDoctorDao.isExist(consultCode, doctorTeamMember.getMemberCode()) == 0) {
                    doctor = doctorDao.findByCode(doctorTeamMember.getMemberCode());//专科医生
                    if (doctor != null) {
                        json = new JSONObject();
                        json.put("code", doctor.getCode());
                        json.put("name", doctor.getName());
                        json.put("photo", doctor.getPhoto());
                        json.put("id", doctor.getId());
                        json.put("hospital", doctor.getHospital());
                        json.put("hosptialName", doctor.getHospitalName());
                        newDoctors.add(json);
                    }
                }
            }

            if (rs != null) {
                for (Map m : rs) {
                    json = new JSONObject();
                    json.put("code", m.get("code"));
                    json.put("name", m.get("name"));
                    json.put("photo", m.get("photo"));
                    json.put("id", m.get("id"));
                    json.put("hospital", m.get("hospital"));
                    json.put("hosptialName", m.get("hospital_name"));
                    newDoctors.add(json);
                }
            }

            returnMap.put("doctors", newDoctors);
            int total = countNoInConsultDoctor(existDoc, consultCode);
            returnMap.put("totalPage", total / pageSzie + (total % pageSzie > 0 ? 1 : 0));
        } else {
            //三师只可以邀请自己的专科医生
            //查找病人所在的团队
            DoctorTeam doctorTeam = doctorTeamDao.findByParientCodeAndSignType(parientCode, consult.getType() + "");
            DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findDoctor2ByTeam(doctorTeam.getCode(), 1);
            Doctor doctor = doctorDao.findByCode(doctorTeamMember.getMemberCode());
            List<JSONObject> newDoctors = new ArrayList<>();

            JSONObject json = new JSONObject();
            json.put("code", doctor.getCode());
            json.put("name", doctor.getName());
            json.put("photo", doctor.getPhoto());
            json.put("id", doctor.getId());
            json.put("hospital", doctor.getHospital());
            json.put("hosptialName", doctor.getHospitalName());
            newDoctors.add(json);

            returnMap.put("doctors", newDoctors);
            returnMap.put("totalPage", 1);
        }
        return returnMap;
    }

    @Transactional
    public List<Doctor> findDoctorByLevelAndHospital(String hospital, Integer level) {
        return doctorDao.findDoctorByLevelAndHospital(hospital, level);
    }

    /**
     * 更新医生身份证号
     *
     * @param idcard
     * @param doctor
     * @return
     */
    @Transactional
    public boolean updateDoctorIdcard(String idcard, String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if (doc == null) {
            throw new Exception("医生不存在");
        }
        doc.setIdcard(idcard);
        return true;
    }

    /**
     * 更新医生专长
     *
     * @param expertise
     * @param doctor
     * @return
     */
    @Transactional
    public boolean updateExpertise(String expertise, String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if (doc == null) {
            throw new Exception("医生不存在");
        }
        doc.setExpertise(expertise);
        return true;
    }

    /**
     * 更新医生性别
     *
     * @param sex
     * @param doctor
     * @return
     */
    @Transactional
    public boolean updateSex(int sex, String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if (doc == null) {
            throw new Exception("医生不存在");
        }
        doc.setSex(sex);
        return true;
    }

    /**
     * 更新医生介绍
     *
     * @param introduce
     * @param doctor
     * @return
     */
    @Transactional
    public boolean updateIntroduce(String introduce, String doctor) throws Exception {
        Doctor doc = doctorDao.findByCode(doctor);
        if (doc == null) {
            throw new Exception("医生不存在");
        }
        doc.setIntroduce(introduce);
        return true;
    }

    /**
     * 设置医生为名医
     *
     * @param doctorCode
     */
    @Transactional
    public void setFamous(String doctorCode, Integer status) {
        Doctor doctor = doctorDao.findByCode(doctorCode);
        //如果是空或者大于1 默认是关闭名医
        if (status == null || status > 1) {
            status = 0;
        }
        doctor.setIsFamous(status);
    }

    @Transactional
    public Page<Doctor> findDoctorByDept(String dept, String hosptial, String key, int page, int pageSize) {
        if (pageSize <= 0) {
            pageSize = 10;
        }
        if (page <= 0) {
            page = 1;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "name");
        // 分页信息
        PageRequest pageRequest = new PageRequest(page - 1, pageSize, sort);
        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(key)) {
            filters.put("name", new SearchFilter("name", SearchFilter.Operator.LIKE, key));
        }
        if (StringUtils.isNotEmpty(dept)) {
            filters.put("dept", new SearchFilter("dept", SearchFilter.Operator.EQ, dept));
        }
        if (StringUtils.isNotEmpty(hosptial)) {
            filters.put("hosptial", new SearchFilter("hosptial", SearchFilter.Operator.EQ, hosptial));
        }
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);

        return doctorDao.findAll(spec, pageRequest);
    }


    @Transactional
    public Page<Doctor> findFamousDoctor(String key, Integer type, int page, int pageSize, Integer level) {
        if (pageSize <= 0) {
            pageSize = 10;
        }
        if (page <= 0) {
            page = 1;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "name");
        // 分页信息
        PageRequest pageRequest = new PageRequest(page - 1, pageSize, sort);
        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(key)) {
            filters.put("name", new SearchFilter("name", SearchFilter.Operator.LIKE, key));
        }

        filters.put("isFamous", new SearchFilter("isFamous", SearchFilter.Operator.EQ, type));

        if (level != null && level > 0 && level < 4) {
            filters.put("level", new SearchFilter("level", SearchFilter.Operator.EQ, level));
        }
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);

        return doctorDao.findAll(spec, pageRequest);
    }


    @Transactional
    public List<Doctor> findFamousDoctorList(String key, Integer type, int page, int pageSize, Integer level) throws Exception {
        if (pageSize <= 0) {
            pageSize = 10;
        }
        if (page <= 0) {
            page = 1;
        }
        // 排序
        Sort sort = new Sort(Sort.Direction.DESC, "name");

        // 查询全部
        Map<String, SearchFilter> filters = new HashMap<String, SearchFilter>();
        if (StringUtils.isNotEmpty(key)) {
            filters.put("name", new SearchFilter("name", SearchFilter.Operator.LIKE, key));
        }

        if (type == 1) {
            filters.put("isFamous", new SearchFilter("isFamous", SearchFilter.Operator.EQ, type));
        }

        if (level != null && level > 0 && level < 4) {
            filters.put("level", new SearchFilter("level", SearchFilter.Operator.EQ, level));
        }
        Specification<Doctor> spec = DynamicSpecifications.bySearchFilter(filters.values(), Doctor.class);

        List<Doctor> doctors = doctorDao.findAll(spec, sort);
        List<Doctor> workingDoctor = new ArrayList<>();
        List<Doctor> returnList = new ArrayList<>();
        int start = (page - 1) * pageSize;
        int end = start + pageSize;

        if (doctors.size() > 0) {
            for (Doctor doc : doctors) {
                if (workingDoctor.size() > end) {
                    break;
                }
                if (type != 1) {
                    if (doc.getIsFamous() != null && doc.getIsFamous() == 1) {
                        continue;
                    }
                }
                JSONObject iswork = type == 1 ? workTimeService.isFamousDoctorWorking(doc.getCode()) : workTimeService.isDoctorWorking(doc.getCode());
                if (iswork.getString("status").equals("1")) {
                    workingDoctor.add(doc);
                }
            }

            if (end > workingDoctor.size()) {
                end = workingDoctor.size();
            }

            if (start < workingDoctor.size()) {
                returnList = workingDoctor.subList(start, end);
            }
        }

        return returnList;
    }

    @Transactional
    public JSONArray findWorkingDoctorListByDept(String dept, String hospital, String level, String key, int page, int pagesize) throws Exception {
        String sql = "select * from wlyy_doctor where  status = 1";
        List<Object> args = new ArrayList<>();

        if (!StringUtils.isEmpty(dept)) {
            sql += " and dept = ? ";
            args.add(dept);
        }
        if (!StringUtils.isEmpty(hospital)) {
            sql += " and hospital = ? ";
            args.add(hospital);
        }
        if (!StringUtils.isEmpty(level)) {
            sql += " and level = ? ";
            args.add(Integer.valueOf(level));
        }
        if (!StringUtils.isEmpty(key)) {
            sql += " and name like ? ";
            args.add("%" + key + "%");
        }

        if (page >= 0) {
            sql += " limit " + page * pagesize + "," + pagesize;
        }

        List<Doctor> doctors = jdbcTemplate.query(sql, args.toArray(), new BeanPropertyRowMapper(Doctor.class));
        JSONArray workingDoctor = new JSONArray();
        if (doctors.size() > 0) {
            for (Doctor doc : doctors) {
                JSONObject iswork = workTimeService.isDoctorWorking(doc.getCode());
                if (iswork.getString("status").equals("1")) {
                    JSONObject docJson = new JSONObject(doc);
                    if (docJson.has("password")) {
                        docJson.remove("password");
                    }
                    if (docJson.has("salt")) {
                        docJson.remove("salt");
                    }
                    workingDoctor.put(docJson);
                }
            }
        }

        return workingDoctor;
    }


    @Transactional
    public void updateTeamHealthDoctor(String newDoctorCode, String oldDoctorCode, String patient) throws Exception {
        //得到患者的签约信息
        SignFamily signFamily = signFamilyDao.findByPatient(patient);
        //得到签约中的健管师
        oldDoctorCode = signFamily.getDoctorHealth();
        //如果存在旧的健管师
        if (!org.springframework.util.StringUtils.isEmpty(oldDoctorCode)) {
            //判断患者对旧的健管师是否存在健康咨询
            ConsultTeam consultTeam = consultTeamDao.findByParientCodeAndSignTypeAndDoctor(patient, oldDoctorCode, 2);
            if (consultTeam != null) {
                throw new Exception("存在没有关闭的健康咨询");
            }
            //修改医生服务团队 删除旧的健康管理师
            DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findMemberByTeamAndCode(signFamily.getTeamCode(), oldDoctorCode);
            if (doctorTeamMember != null) {
                doctorTeamMember.setDel("0");
            }
        }
        Doctor newD = doctorDao.findByCode(newDoctorCode);
        String oldDoctorHealthName = signFamily.getDoctorHealthName();

        //修改签约中的健康管理师
        signFamily.setDoctorHealth(newD.getCode());
        signFamily.setDoctorHealthName(newD.getName());

        //添加新的健康管理师到服务团队里
        DoctorTeamMember newDoctorTeamMember = new DoctorTeamMember();
        newDoctorTeamMember.setTeam(signFamily.getTeamCode());
        newDoctorTeamMember.setCzrq(new Date());
        newDoctorTeamMember.setName(newD.getName());
        newDoctorTeamMember.setMemberCode(newD.getCode());
        newDoctorTeamMember.setType(3);
        newDoctorTeamMember.setSignType("2");
        newDoctorTeamMember.setDel("1");
        newDoctorTeamMember.setCode(UUID.randomUUID().toString().replace("-", ""));
        doctorTeamDoctor.save(newDoctorTeamMember);

        Patient p = patientDao.findByCode(patient);
        JSONObject data = new JSONObject();
        if (StringUtils.isNotEmpty(oldDoctorCode)) {
            data.put("toUser", patient);
            data.put("doctor", newD.getCode());
            data.put("doctorName", newD.getName());
            data.put("first", p.getName() + "，您好！因签约团队内分工调整，您的责任医生有变动，" + oldDoctorHealthName +
                    "医生无法继续为您服务，具体变动如下：");
            data.put("keyword3", "家庭医生");
            data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
            data.put("keyword1", newD.getName());
            if (StringUtils.isEmpty(signFamily.getDoctor()) || signFamily.getDoctorHealth().equals(signFamily.getDoctor())) {
                data.put("remark", newD.getName() + "医生将专门为您提供优质健康服务");
            } else {
                data.put("remark", newD.getName() + "医生与" + signFamily.getDoctorName() + "医生一道，为您提供优质健康服务");
            }
        } else {
            data.put("toUser", patient);
            data.put("doctor", newD.getCode());
            data.put("doctorName", newD.getName());
            data.put("first", p.getName() + "，您好！您的签约团队已为您新增一位责任医生，医生信息如下：");
            data.put("keyword3", "家庭医生");
            data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
            data.put("keyword1", newD.getName());
            if (StringUtils.isEmpty(signFamily.getDoctor()) || signFamily.getDoctorHealth().equals(signFamily.getDoctor())) {
                data.put("remark", newD.getName() + "医生将专门为您提供优质的健康服务");
            } else {
                data.put("remark", newD.getName() + "医生与" + signFamily.getDoctorName() + "医生一道，为您提供优质健康服务");
            }
        }
        PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, p.getOpenid(), p.getName(), data);
    }

    @Transactional
    public Map<String, Integer> updateTeamHealthDoctors(String newDoctorCode, String oldDoctorCode, String patients, String loginUser) throws Exception {
        Map<String, Integer> returnMap = new HashMap();
        String[] patiensString = patients.split(",");
        Integer successs = 0;//转移成功
        Integer error = 0;//转移失败
        for (int i = 0; i < patiensString.length; i++) {
            try {
                updateTeamHealthDoctor(newDoctorCode, oldDoctorCode, patiensString[i]);
                successs++;
            } catch (Exception e) {
                error++;
            }
        }
        OperatorLog operatorLog = new OperatorLog();
        operatorLog.setCreateTime(new Date());
        operatorLog.setMethod("/doctor/updateTeamHealthDoctors");
        operatorLog.setMethodName("转换团队中的健康管理师:成功:" + successs + "，失败:" + error);
        operatorLog.setCreateUser(loginUser);
        JSONObject jo = new JSONObject();
        jo.put("newDoctorCode", newDoctorCode);
        jo.put("oldDoctorCode", oldDoctorCode);
        jo.put("patients", patients);
        operatorLog.setParams(jo.toString());
        operatorLogDao.save(operatorLog);
        returnMap.put("success", successs);
        returnMap.put("error", error);
        return returnMap;
    }

    @Transactional
    public int updateTeamHealthDoctorsAll(String newDoctorCode, String doctor) throws Exception {
        List<String> patients = signFamilyDao.findNohealthByDoctor(doctor);
        boolean hasNoTeam = false;
        if (patients != null) {
            for (String patient : patients) {
                try {
                    if (updateTeamHealthDoctorAll(newDoctorCode, patient) == -1) {
                        hasNoTeam = true;
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }

        return hasNoTeam ? 2 : 1;
    }

    @Transactional
    public int updateTeamHealthDoctorAll(String newDoctorCode, String patient) throws Exception {
        //得到患者的签约信息
        SignFamily signFamily = signFamilyDao.findByPatient(patient);
        if (StringUtils.isEmpty(signFamily.getTeamCode())) {
            return -1;
        }

        if (StringUtils.isNotEmpty(signFamily.getDoctorHealth())) {
            return -2;
        }

        Doctor newD = doctorDao.findByCode(newDoctorCode);
        //修改签约中的健康管理师
        signFamily.setDoctorHealth(newD.getCode());
        signFamily.setDoctorHealthName(newD.getName());

        //添加新的健康管理师到服务团队里
        DoctorTeamMember newDoctorTeamMember = new DoctorTeamMember();
        newDoctorTeamMember.setTeam(signFamily.getTeamCode());
        newDoctorTeamMember.setCzrq(new Date());
        newDoctorTeamMember.setName(newD.getName());
        newDoctorTeamMember.setMemberCode(newD.getCode());
        newDoctorTeamMember.setType(3);
        newDoctorTeamMember.setSignType("2");
        newDoctorTeamMember.setDel("1");
        newDoctorTeamMember.setCode(UUID.randomUUID().toString().replace("-", ""));
        doctorTeamDoctor.save(newDoctorTeamMember);


        Patient p = patientDao.findByCode(patient);
        JSONObject data = new JSONObject();
        data.put("toUser", patient);
        data.put("doctor", newD.getCode());
        data.put("doctorName", newD.getName());
        data.put("first", p.getName() + "，您好！您的签约团队已为您新增一位责任医生，医生信息如下：");
        data.put("keyword3", "家庭医生");
        data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
        data.put("keyword1", newD.getName());
        if (StringUtils.isEmpty(signFamily.getDoctor()) || signFamily.getDoctorHealth().equals(signFamily.getDoctor())) {
            data.put("remark", newD.getName() + "医生将专门为您提供优质的健康服务");
        } else {
            data.put("remark", newD.getName() + "医生与" + signFamily.getDoctorName() + "医生一道，为您提供优质健康服务");
        }
        PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, p.getOpenid(), p.getName(), data);

        return 1;
    }

    /**
     * 医生更换手机号
     *
     * @param doctor  医生code
     * @param mobile  新手机号
     * @param captcha 验证码
     * @return
     */
    @Transactional
    public int changeMobile(String doctor, String mobile, String captcha, int type) {
        Doctor doc = doctorDao.findByCode(doctor);

        if (doc == null) {
            return -1;
        }

        Doctor docMobile = doctorDao.findByMobile(mobile);

        if (docMobile != null && !docMobile.getCode().equals(doctor)) {
            return -2;
        }

        // 验证码验证
        int smsCheck = smsService.check(mobile, type == 1 ? 8 : 9, captcha);
        // 验证失败，不允许变更
        if (smsCheck != 1) {
            return -3;
        }
        //修改密码
        String oldPassword = doc.getPassword();
        //判断旧的密码是不是手机号码后六位
        String oldMobile = doc.getMobile();
        if (!org.springframework.util.StringUtils.isEmpty(oldMobile)) {
            String passwordTemp = oldMobile.substring(5);
            passwordTemp = MD5.GetMD5Code(passwordTemp + doc.getSalt());
            if (passwordTemp.equals(oldPassword)) {
                //如果密码是原来的电话号码后留位改成现在号码的后留位
                String newPassword = MD5.GetMD5Code(mobile.substring(5) + doc.getSalt());
                doc.setPassword(newPassword);
            }
        }
        doc.setMobile(mobile);

        return 1;
    }

    @Transactional
    public void updatePassword(String newPassword1, String newPassword2, String oldPassword, String doctorCode) throws Exception {
        if (!newPassword1.equals(newPassword2)) {
            throw new Exception("新密码不一致");
        }
        if (newPassword1.equals(oldPassword)) {
            throw new Exception("新旧密码一致");
        }
        Doctor doctor = doctorDao.findByCode(doctorCode);
        String oldPasswordTemp = MD5.GetMD5Code(oldPassword + doctor.getSalt());
        if (!oldPasswordTemp.equals(doctor.getPassword())) {
            throw new Exception("旧密码错误");
        }
        String newPassword1Temp = MD5.GetMD5Code(newPassword1 + doctor.getSalt());
        doctor.setPassword(newPassword1Temp);
    }

    /**
     * 查询患者是否与医生签约
     *
     * @param patient
     * @param doctor
     * @return
     */
    @Transactional
    public boolean isPatientSigned(String patient, String doctor) {
        boolean bo = false;
        //签约团队
        DoctorTeam dt = doctorTeamDao.findByPatientCode(patient);
        DoctorTeam dtSS = doctorTeamDao.findSsTeamByPatientCode(patient);
        //医生是否属于团队成员
        if (dt != null && doctorTeamDoctor.countMemberByTeamAndCode(dt.getCode(), doctor) > 0) {
            bo = true;
        }
        if (dtSS != null && doctorTeamDoctor.countMemberByTeamAndCode(dtSS.getCode(), doctor) > 0) {
            bo = true;
        }

        return bo;
    }

    /**
     * 手机号是否注册
     *
     * @param mobile
     * @return
     */
    @Transactional
    public int isMobileRegister(String mobile) {
        Doctor doc = doctorDao.findByMobile(mobile);

        if (doc != null) {
            return 1;
        } else {
            return 0;
        }
    }

    @Transactional
    public Map<String, Integer> updateTeamDoctors(String newDoctorCode, String oldDoctorCode, String patients, String loginUser) throws Exception {
        Map<String, Integer> returnMap = new HashMap();
        String[] patiensString = patients.split(",");

        Integer successs = 0;//转移成功
        Integer error = 0;//转移失败

        for (int i = 0; i < patiensString.length; i++) {
            try {
                updateTeamDoctor(newDoctorCode, oldDoctorCode, patiensString[i]);
                successs++;
            } catch (Exception e) {
                error++;
            }
        }
        OperatorLog operatorLog = new OperatorLog();
        operatorLog.setCreateTime(new Date());
        operatorLog.setMethod("/doctor/updateTeamDoctors");
        operatorLog.setMethodName("转换团队中的全科医生");
        operatorLog.setCreateUser(loginUser);
        JSONObject jo = new JSONObject();
        jo.put("newDoctorCode", newDoctorCode);
        jo.put("oldDoctorCode", oldDoctorCode);
        jo.put("patients", patients);
        operatorLog.setParams(jo.toString());
        operatorLogDao.save(operatorLog);

        returnMap.put("success", successs);
        returnMap.put("error", error);
        return returnMap;
    }

    private void updateTeamDoctor(String newDoctorCode, String oldDoctorCode, String patient) throws Exception {
        //得到患者的签约信息
        SignFamily signFamily = signFamilyDao.findByPatient(patient);

        //判断患者对旧的全科医生是否存在健康咨询
        ConsultTeam consultTeam = consultTeamDao.findByParientCodeAndSignTypeAndDoctor(patient, oldDoctorCode, 2);
        if (consultTeam != null) {
            throw new Exception("存在没有关闭的健康咨询");
        }
        //修改医生服务团队 删除旧的全科医生
        DoctorTeamMember doctorTeamMember = doctorTeamDoctor.findMemberByTeamAndQkCode(signFamily.getTeamCode(), oldDoctorCode);
        if (doctorTeamMember != null) {
            doctorTeamMember.setDel("0");
        }

        Doctor newD = doctorDao.findByCode(newDoctorCode);
        String oldDoctorName = signFamily.getDoctorName();
        //修改签约中的全科医生
        signFamily.setDoctor(newD.getCode());
        signFamily.setDoctorName(newD.getName());

        //添加新的全科医生到服务团队里
        DoctorTeamMember newDoctorTeamMember = new DoctorTeamMember();
        newDoctorTeamMember.setTeam(signFamily.getTeamCode());
        newDoctorTeamMember.setCzrq(new Date());
        newDoctorTeamMember.setName(newD.getName());
        newDoctorTeamMember.setMemberCode(newD.getCode());
        newDoctorTeamMember.setType(2);
        newDoctorTeamMember.setSignType("2");
        newDoctorTeamMember.setDel("1");
        newDoctorTeamMember.setCode(UUID.randomUUID().toString().replace("-", ""));
        doctorTeamDoctor.save(newDoctorTeamMember);

        Patient p = patientDao.findByCode(patient);
        JSONObject data = new JSONObject();
        data.put("toUser", patient);
        data.put("doctor", newD.getCode());
        data.put("doctorName", newD.getName());
        data.put("first", p.getName() + "，您好！因签约团队内分工调整，您的责任医生有变动，" + oldDoctorName +
                "医生无法继续为您服务，具体变动如下：");
        data.put("keyword3", "家庭医生");
        data.put("keyword2", DateUtil.dateToStrNoSecond(new Date()));
        data.put("keyword1", newD.getName());
        if (StringUtils.isEmpty(signFamily.getDoctorHealth()) || signFamily.getDoctor().equals(signFamily.getDoctorHealth())) {
            data.put("remark", newD.getName() + "医生将专门为您提供优质健康服务");
        } else {
            data.put("remark", newD.getName() + "医生与" + signFamily.getDoctorHealthName() + "医生一道，为您提供优质健康服务");
        }
        PushMsgTask.getInstance().putWxMsg(accessTokenUtils.getAccessToken(), 10, p.getOpenid(), p.getName(), data);
    }
}
