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

import com.yihu.wlyy.entity.demographic.DemographicInfo;
import com.yihu.wlyy.entity.demographic.ResidenceInfo;
import com.yihu.wlyy.entity.dict.FoundationMedicalSystemParam;
import com.yihu.wlyy.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.entity.patient.SocialSecurityInfo;
import com.yihu.wlyy.entity.patient.invitation.PatientInvitationLog;
import com.yihu.wlyy.repository.demographic.ResidenceInfoDao;
import com.yihu.wlyy.repository.demographic.TblBasicDao;
import com.yihu.wlyy.repository.demographic.TblsysParamDao;
import com.yihu.wlyy.repository.doctor.DoctorDao;
import com.yihu.wlyy.repository.patient.PatientDao;
import com.yihu.wlyy.repository.patient.PatientInvitationLogDao;
import com.yihu.wlyy.repository.patient.SignFamilyDao;
import com.yihu.wlyy.repository.patient.SocialSecurityInfoDao;
import com.yihu.wlyy.util.IdCardUtil;
import com.yihu.wlyy.util.SystemConf;
import com.yihu.wlyy.wechat.util.WeiXinTempMsgSendUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Created by Administrator on 2016.08.20.
 */
@Service
public class FamilyService {
    @Autowired
    private TblBasicDao tblBasicDao;
    @Autowired
    private ResidenceInfoDao residenceInfoDao;
    @Autowired
    private TblsysParamDao tblsysParamDao;
    @Autowired
    private PatientInvitationLogDao patientInviteLogDao;
    @Autowired
    private PatientDao patientDao;
    @Autowired
    private SocialSecurityInfoDao socialSecurityInfoDao;
    @Autowired
    private SignFamilyDao signFamilyDao;
    @Autowired
    private DoctorDao doctorDao;
    @Autowired
    private WeiXinTempMsgSendUtils weiXinTempMsgSendUtils;
    @Value("#{sys.doctor_invitel_template}")
    private String templateId;

    //通過患者身份證查找患者家庭成员
    @Transactional
    public JSONArray getfamilyMember(String patientCode, String idcard, String doctorCode) throws Exception {

        JSONArray jsonArray = new JSONArray();

        //设置关系Map --start
        List<FoundationMedicalSystemParam> foundationMedicalSystemParams = tblsysParamDao.findByParamname("Relaholder");
        Map<String, String> relaholderMap = new HashMap<String, String>();
        for (FoundationMedicalSystemParam foundationMedicalSystemParam : foundationMedicalSystemParams) {
            relaholderMap.put(foundationMedicalSystemParam.getCode(), foundationMedicalSystemParam.getParamchina());
        }
        //1.查询卫计委提供的表得到该用户的家庭成员
        DemographicInfo demographicInfo = tblBasicDao.findByIdCard(idcard);//根据得到患者信息
        if (demographicInfo == null) {
            return jsonArray;
        }
        //得到父亲 得到母亲
        if (!StringUtils.isEmpty(demographicInfo.getFatherid())) {
            DemographicInfo father = tblBasicDao.findOne(demographicInfo.getFatherid());
            if (father != null && !StringUtils.isEmpty(father.getCardid())) {
                SocialSecurityInfo socialSecurityInfo = socialSecurityInfoDao.findBySfzh18Max(father.getCardid());
                if (socialSecurityInfo != null) {
                    //没医保卡不返回
                    addParent(relaholderMap, jsonArray, father, "51", doctorCode, patientCode);
                }
            }
        }

        if (!StringUtils.isEmpty(demographicInfo.getMaterid())) {
            DemographicInfo mother = tblBasicDao.findOne(demographicInfo.getMaterid());
            if (mother != null && !StringUtils.isEmpty(mother.getCardid())) {
                SocialSecurityInfo socialSecurityInfo = socialSecurityInfoDao.findBySfzh18Max(mother.getCardid());
                if (socialSecurityInfo != null) {
                    //没医保卡不返回
                    addParent(relaholderMap, jsonArray, mother, "52", doctorCode, patientCode);
                }
            }
        }
        //得到当前患者的戶口信息
        List<ResidenceInfo> residenceInfos = residenceInfoDao.findByPersonId(demographicInfo.getPersonid());

        //判断是否为空
        if (residenceInfos != null && residenceInfos.size() > 0) {
            for (ResidenceInfo residenceInfo : residenceInfos) {

                //得到戶主關係中出乎原因是空的 说明这条是最新的户主信息
                if (StringUtils.isEmpty(residenceInfo.getLeavecau())) {
                    //判断当前用户是不是户主 不是户主不查询
                    if (!"02".equals(residenceInfo.getRelaholder())) {
                        continue;
                    }

                    List<ResidenceInfo> residenceInfoTemps = residenceInfoDao.findByFamilyId(residenceInfo.getFamilystateid());
                    for (ResidenceInfo personjoinfamilymid : residenceInfoTemps) {
                        //排除自己本身,和排除没有亲戚关系的 和排除父母亲
                        if ((!personjoinfamilymid.getPersonid().equals(demographicInfo.getPersonid())) &&
                                (!"99".equals(personjoinfamilymid.getRelaholder())) &&
                                (!"51".equals(personjoinfamilymid.getRelaholder())) &&
                                (!"52".equals(personjoinfamilymid.getRelaholder()))) {
                            JSONObject jo = new JSONObject();

                            //设置户主关系
                            jo.put("relaholder", relaholderMap.get(personjoinfamilymid.getRelaholder()));
                            DemographicInfo holderInfo = tblBasicDao.findOne(personjoinfamilymid.getPersonid());
                            SocialSecurityInfo socialSecurityInfo = socialSecurityInfoDao.findBySfzh18Max(holderInfo.getCardid());
                            if (socialSecurityInfo == null || StringUtils.isEmpty(socialSecurityInfo.getCardno())) {
                                continue;
                            }

                            jo.put("name", holderInfo.getName());
                            jo.put("sex", holderInfo.getSex());
                            jo.put("idcard", holderInfo.getCardid());
                            jo.put("addressCode", holderInfo.getNowaddress());
                            jo.put("addressName", holderInfo.getNowaddressinfo());

                            //根据身份证判断是否有三师签约
                            SignFamily sssignFamily = signFamilyDao.findSSByIdcard(holderInfo.getCardid());
                            if (sssignFamily != null && !doctorCode.equals(sssignFamily.getDoctor())) {
                                //如果有三师签约并且医生不一样显示已经签约
                                jo.put("status", "3");
                            } else {
                                //根据身份证判断是否签约
                                SignFamily signFamily = signFamilyDao.findByIdcard(holderInfo.getCardid());
                                //设置状态 0可邀请 1已邀请 2待签约 3已签约
                                //判断是否邀请
                                //得到用户
                                Patient familyPatient = patientDao.findByIdcard(holderInfo.getCardid());

                                //判断是否签约
                                if (signFamily != null) {
                                    if (0 == signFamily.getStatus()) {
                                        jo.put("status", "2");
                                    } else {
                                        jo.put("status", "3");
                                    }
                                } else {
                                    if (familyPatient != null) {
                                        jo.put("code", familyPatient.getCode());
                                        List<PatientInvitationLog> patientInvitationLog = patientInviteLogDao.getPatientInviteLog(doctorCode, patientCode, familyPatient.getCode());
                                        if (patientInvitationLog != null && patientInvitationLog.size() > 0) {
                                            jo.put("status", "1");
                                        } else {
                                            jo.put("status", "0");
                                        }
                                    } else {
                                        jo.put("status", "0");
                                    }
                                }
                            }
                            jsonArray.put(jo);
                        }
                    }
                }
            }
        }
        //2.判断家庭成员是否已经注册 没有注册就直接注册他的家庭成员
        for (Object object : jsonArray) {
            JSONObject jo = (JSONObject) object;
            if (!StringUtils.isEmpty(jo.get("idcard"))) {
                Patient patient = patientDao.findByIdcard(jo.get("idcard").toString());
                if (patient == null) {
                    //如果先前没有注册那就是注册
                    Patient patientTemp = new Patient();
                    jo.put("code", patientTemp.getCode());//设置患者code
                    String patientCodeTmep = UUID.randomUUID().toString().replaceAll("-", "");
                    patientTemp.setCode(patientCodeTmep);
                    patientTemp.setIdcard(jo.get("idcard").toString());
                    if (!StringUtils.isEmpty(jo.get("name"))) {
                        patientTemp.setName(jo.get("name").toString());
                    }
                    patientTemp.setSex(Integer.valueOf(IdCardUtil.getSexForIdcard(jo.get("idcard").toString())));
                    patientTemp.setBirthday(IdCardUtil.getBirthdayForIdcard(jo.get("idcard").toString()));
                    SocialSecurityInfo socialSecurityInfo = socialSecurityInfoDao.findBySfzh18Max(jo.get("idcard").toString());
                    //设置医保卡号
                    if (socialSecurityInfo != null && !(StringUtils.isEmpty(socialSecurityInfo.getCardno()))) {
                        patientTemp.setSsc(socialSecurityInfo.getCardno());
                    } else {
                        //没医保卡不用注册
                        continue;
                    }
                    if (!StringUtils.isEmpty(jo.get("addressName"))) {
                        patientTemp.setAddress(jo.get("addressName").toString());
                    }
                    if (!StringUtils.isEmpty(jo.get("addressCode"))) {
                        patientTemp.setStreet(jo.get("addressCode").toString());
                    }
                    if (!StringUtils.isEmpty(jo.get("addressName"))) {
                        patientTemp.setStreetName(jo.get("addressName").toString());
                    }
                    patientTemp.setStatus(1);
                    patientTemp.setCzrq(new Date());
                    patientTemp.setDisease(0);
                    patientTemp.setPoints(0);
                    patientTemp.setRecordAmount(0);
                    patientDao.save(patientTemp);
                    jo.put("code",patientTemp.getCode());
                }else{
                    jo.put("code",patient.getCode());
                }
            }
        }

        //3.返回家庭成员信息
        return jsonArray;
    }

    @Transactional
    private void addParent(Map<String, String> relaholderMap, JSONArray jsonArray, DemographicInfo father, String relationName, String doctorCode, String patientCode) {
        JSONObject jo = new JSONObject();
        //设置户主关系
        jo.put("relaholder", relaholderMap.get(relationName));
        DemographicInfo demographicInfo = tblBasicDao.findOne(father.getPersonid());
        //设置名称
        jo.put("name", demographicInfo.getName());
        //设置性别
        jo.put("sex", demographicInfo.getSex());
        //设置身份证
        jo.put("idcard", demographicInfo.getCardid());
        //设置地址编码 12位
        jo.put("addressCode", demographicInfo.getNowaddress());
        //设置地址名称 12位
        jo.put("addressName", demographicInfo.getNowaddressinfo());

        //根据身份证判断是否有三师签约
        SignFamily sssignFamily = signFamilyDao.findSSByIdcard(demographicInfo.getCardid());
        if (sssignFamily != null && !doctorCode.equals(sssignFamily.getDoctor())) {
            //如果有三师签约并且医生不一样
            jo.put("status", "3");
        } else {
            //根据身份证判断是否有家庭签约
            SignFamily signFamily = signFamilyDao.findByIdcard(demographicInfo.getCardid());
            //设置状态 0可邀请 1已邀请 2待签约 3已签约
            //判断是否签约
            if (signFamily != null) {
                if (0 == signFamily.getStatus()) {
                    jo.put("status", "2");
                } else {
                    jo.put("status", "3");
                }
            } else {
                //判断是否邀请
                //得到用户
                Patient familyPatient = patientDao.findByIdcard(demographicInfo.getCardid());
                if (familyPatient != null) {
                    jo.put("code", familyPatient.getCode());
                    List<PatientInvitationLog> patientInvitationLog = patientInviteLogDao.getPatientInviteLog(doctorCode, patientCode, familyPatient.getCode());
                    if (patientInvitationLog != null && patientInvitationLog.size() > 0) {
                        jo.put("status", "1");
                    } else {
                        jo.put("status", "0");
                    }
                } else {
                    jo.put("status", "0");
                }
            }
        }
        jsonArray.put(jo);
    }

    @Transactional
    public String inviteFamilyMember(String patientCode, String currentPatientCode, String doctorCode, String relation) throws Exception {
        //得到患者
        Patient patient = patientDao.findByCode(patientCode);
        Patient currentPatient = patientDao.findByCode(currentPatientCode);
        Doctor doctor = doctorDao.findByCode(doctorCode);

        //判断患者是否有三师签约
        SignFamily sssignFamily = signFamilyDao.findBySanshiIdcard(patient.getIdcard());
        if (sssignFamily != null) {
            if (!sssignFamily.getDoctor().equals(doctorCode)) {
                return "-3";
            }
        }
        //添加邀请记录
        //判断患者是否有签约
        SignFamily signFamily = signFamilyDao.findByIdcard(patient.getIdcard());
        if (signFamily != null) {
            return "-1";
        }
        //判断医生是否有邀请过这个患者
        List<PatientInvitationLog> patientInvitationLogs = patientInviteLogDao.getPatientInviteLog(doctorCode, patientCode, currentPatientCode);
        if (patientInvitationLogs != null && patientInvitationLogs.size() > 0) {
            return "-2";
        }
        String code = UUID.randomUUID().toString().replaceAll("-", "");
        PatientInvitationLog patientInvitationLog = new PatientInvitationLog();
        patientInvitationLog.setId(code);
        patientInvitationLog.setInviteDoctorCode(doctor.getCode());
        patientInvitationLog.setInviteDoctorName(doctor.getName());
        patientInvitationLog.setInvitePatientCode(patient.getCode());
        patientInvitationLog.setInvitePatientName(patient.getName());
        patientInvitationLog.setInviteTime(new Date());
        patientInvitationLog.setDealPatientCode(currentPatient.getCode());
        patientInvitationLog.setDealPatientName(currentPatient.getName());
        patientInvitationLog.setDealType("0");
        patientInvitationLog.setRelationType(relation);
        if(StringUtils.isEmpty(currentPatient.getOpenid())){
            patientInvitationLog.setWxPush("1");//设置未推送
        }else{
            patientInvitationLog.setWxPush("0");//设置成已经推送
            patientInvitationLog.setWxPushTime(new Date());
            send(currentPatient, patient , doctor, code);

        }
        patientInviteLogDao.save(patientInvitationLog);
        return "1";
    }

    private void send(Patient currentPatient, Patient patient , Doctor doctor, String code) throws Exception {
        //发送模板
        Properties systemConf = SystemConf.getInstance().getSystemProperties();
        String openId = currentPatient.getOpenid();
        //模板数据
        JSONObject json = new JSONObject();
        JSONObject first = new JSONObject();
        String firstString = currentPatient.getName() + "先生/小姐，再次感谢您对我的信任。同时，我也衷心地希望能够拥有为您整个家庭提供温馨服务的荣幸。在此诚意地邀请您为" + patient.getName() + "进行签约";
        first.put("value", firstString);
        first.put("color", "#173177");
        json.put("first", first);

        JSONObject content1 = new JSONObject();
        String content1String = doctor.getName();
        content1.put("value", content1String);
        content1.put("color", "#173177");
        json.put("keyword1", content1);

        JSONObject content2 = new JSONObject();
        content2.put("value", new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date()));
        content2.put("color", "#173177");
        json.put("keyword2", content2);
        /**
         *    "first": {
         "value":"恭喜你购买成功！",
         "color":"#173177"
         },
         "keynote1":{
         "value":"巧克力",
         "color":"#173177"
         },
         "keynote2": {
         "value":"39.8元",
         "color":"#173177"
         },
         */
        //填充url
        String url = systemConf.getProperty("doctor_invitel_url");
        url = url.replace("{server}", systemConf.getProperty("wechat_base_url"))
                .replace("{appId}", systemConf.getProperty("appId"))//appid
                .replace("{doctorCode}", doctor.getCode())//医生code;
                .replace("{invilogcode}", code)//邀请记录code
                .replace("{currentPatient}", currentPatient.getCode())//当前用户的code
                .replace("{currentZH}", currentPatient.getMobile());//当前用户的账号
        //发送模板
        JSONObject end = new JSONObject();
        end.put("value", "【点击帮助您的家庭成员完成签约】");
        end.put("color", "#173177");
        json.put("remark", end);
        System.out.println("发送邀请信息:templateId:"+templateId+",openId:"+openId+",url:"+url+",json:"+json);
        weiXinTempMsgSendUtils.sendTemplateMessage(templateId, openId, url, json);
    }

    /**
     * 查询邀请记录
     *
     * @param doctorCode
     * @param patientCode
     * @param invitePatientCode
     * @return
     */
    public PatientInvitationLog getPatientInviteLog(String doctorCode, String patientCode, String invitePatientCode) {
        return patientInviteLogDao.getPatientInviteLog(doctorCode, patientCode, invitePatientCode).get(0);
    }

    /**
     * 更新邀请记录
     *
     * @param patientInviteLogCode
     * @param uid
     * @param type
     */
    @Transactional
    public void updatePatientInviteLog(String patientInviteLogCode, String uid, String type) {
        PatientInvitationLog patientInvitationLog = patientInviteLogDao.findOne(patientInviteLogCode);
        patientInvitationLog.setDealType(type);
        patientInvitationLog.setDealTime(new Date());
    }

    public PatientInvitationLog getPatientInviteLog(String invitePatientCode) {
        return patientInviteLogDao.findOne(invitePatientCode);
    }

    @Transactional
    public void sendWXMessage(Patient patient)throws  Exception {
        //得到患者为发送微信模板的的邀请纪录
        List<PatientInvitationLog> patientInvitationLogs =patientInviteLogDao.findByDealPatientAndWXPush_1(patient.getCode());
        for (PatientInvitationLog patientInvitationLog : patientInvitationLogs){
            Patient invitePatient=patientDao.findByCode(patientInvitationLog.getInvitePatientCode());//邀请的家人
            Doctor doctor=doctorDao.findByCode(patientInvitationLog.getInviteDoctorCode());//医生
            send(patient,invitePatient,doctor, patientInvitationLog.getId().toString());//发送微信模板
            //更新邀请纪录为已经推送
            patientInvitationLog.setWxPush("0");
            patientInvitationLog.setWxPushTime(new Date());
        }
    }
}
