package com.yihu.wlyy.web.doctor.sign;

import java.net.URLDecoder;
import java.util.Map;

import com.yihu.wlyy.entity.message.Message;
import com.yihu.wlyy.service.app.account.PatientInfoService;
import com.yihu.wlyy.util.*;
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.data.redis.core.StringRedisTemplate;
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.entity.doctor.profile.Doctor;
import com.yihu.wlyy.entity.patient.Patient;
import com.yihu.wlyy.entity.patient.SignFamily;
import com.yihu.wlyy.service.app.sign.FamilyContractService;
import com.yihu.wlyy.service.common.account.DoctorService;
import com.yihu.wlyy.service.common.account.PatientService;
import com.yihu.wlyy.web.WeixinBaseController;

/**
 * 医生端：家庭签约控制类
 *
 * @author George
 */
@Controller
@RequestMapping(value = "/doctor/family_contract")
@Api(description = "医生端-家庭签约")
public class DoctorFamilyContractController extends WeixinBaseController {

    @Autowired
    private FamilyContractService familyContractService;
    @Autowired
    private DoctorService doctorService;
    @Autowired
    private PatientService patientService;
    @Autowired
    PatientInfoService patientInfoService;
    @Autowired
    StringRedisTemplate redisTemplate;

    /**
     * 医生签约患者列表查询接口
     *
     * @param type     0全部，1待签约，2已签约，3待解约，4已解约
     * @param id
     * @param pagesize 分页大小
     * @return
     */
    @RequestMapping(value = "list")
    @ResponseBody
    public String list(int type, long id, int pagesize) {
        try {
            JSONArray array = new JSONArray();
            Page<SignFamily> list = familyContractService.findSignByDoctor(type, id, pagesize);
            if (list != null) {
                for (SignFamily sf : list) {
                    if (sf == null) {
                        continue;
                    }
                    JSONObject json = new JSONObject();
                    json.put("id", sf.getId());
                    // 签约标识
                    json.put("code", sf.getCode());
                    // 签约医院名称
                    json.put("hospital_name", sf.getHospitalName());
                    // 签约医生姓名
                    json.put("doctor_name", sf.getDoctorName());
                    // 开始日期
                    json.put("begin", DateUtil.dateToStrShort(sf.getBegin()));
                    // 结束日期
                    json.put("end", DateUtil.dateToStrShort(sf.getEnd()));
                    // 签约状态(-1患者已取消，-2已拒绝，-3已解约，-4已到期，0待签约，1已签约，2患者申请取消签约，3医生申请取消签约
                    json.put("status", sf.getStatus());
                    array.put(json);
                }
            }
            return write(200, "签约数据加载成功！", "list", array);
        } catch (Exception e) {
            error(e);
            return error(-1, "签约数据加载失败！");
        }
    }

    /**
     * 校验是否有签约信息
     *
     * @param idcard
     * @return
     */
    @RequestMapping(value = "check")
    @ResponseBody
    public String checkSign(String idcard) {
        try {
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空！");
            }
            JSONObject json = new JSONObject();
            // 解密身份证号
            idcard = RSAUtils.getInstance(familyContractService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "请输入身份证号！");
            }
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号！");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号！");
            }

            Patient patient = patientService.findByIdcard(idcard);
            if (patient == null) {
                // 未签约
                json.put("sign", 2);
            } else {
                json = familyContractService.checkSign(patient);
                if (json == null) {
                    return error(-1, "签约验证异常！");
                }
            }
            return write(200, "签约验证成功！", "data", json);
        } catch (Exception e) {
            error(e);
            return error(-1, "签约验证异常！");
        }
    }

    /**
     * 手工代签约接口
     *
     * @param name       患者名称
     * @param idcard     身份证号
     * @param ssc        社保卡号
     * @param mobile     手机号
     * @param group      患者组 1是健康人群组 2是慢病  3是65岁以上人群
     * @param emerMobile 应急人手机号
     * @param images     图片URL，多图以逗号分隔
     * @param expenses   签约费用
     * @return
     */
    @RequestMapping(value = "agent")
    @ResponseBody
    public String agent(
            String name,
            String idcard,
            @RequestParam(required = false) String ssc,
            String mobile,
            @RequestParam(required = false, defaultValue = "") String disease,
            @RequestParam(required = false) String emerMobile,
            @RequestParam(required = false) String majorDoctor,
            @RequestParam(required = false) String majorDoctorName,
            String healthDoctor,
            String healthDoctorName,
            String images,
            @RequestParam(required = false, defaultValue = "0") String expenses,
            String doctor,//全科医生code
            String doctorName,//全科医生名字
            String signDoctorCode,//簽約人code
            String signDoctorName,//簽約人銘
            String signDoctorLevel,//簽約人等级
            @RequestParam(required = false) String group //分组
    ) {
        try {
            //选择病种时需指定专科医生
//            if (StringUtils.isNotEmpty(disease)) {
//                if (!disease.equals("0") && (StringUtils.isEmpty(majorDoctor) || StringUtils.isEmpty(majorDoctorName))) {
//                    return error(-1, "请输入专科医生!");
//                }
//            }
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "请输入身份证号！");
            }
            if (StringUtils.isEmpty(healthDoctor) || StringUtils.isEmpty(healthDoctorName)) {
                return error(-1, "请选择健康管理师！");
            }
            // 解密身份证号
            idcard = RSAUtils.getInstance(familyContractService).decryptString(idcard);
            idcard = URLDecoder.decode(idcard, "UTF-8");
            idcard = StringUtils.reverse(idcard);
            // 校验身份证号
            IdcardValidator validator = new IdcardValidator();
            if (validator.isValidatedAllIdcard(idcard)) {
                if (idcard.length() == 15) {
                    idcard = validator.convertIdcarBy15bit(idcard);
                    if (StringUtils.isEmpty(idcard)) {
                        return error(-1, "请输入正确的身份证号！");
                    }
                }
            } else {
                return error(-1, "请输入正确的身份证号！");
            }

            if (StringUtils.isEmpty(name)) {
                return error(-1, "姓名不允许为空！");
            }
            if (StringUtils.isEmpty(idcard)) {
                return error(-1, "身份证号不允许为空！");
            }
            if (StringUtils.isEmpty(ssc)) {
                return error(-1, "社保卡号不允许为空！");
            }
            if (StringUtils.isEmpty(mobile)) {
                return error(-1, "手机号不允许为空！");
            }
            int amount = familyContractService.hasSingStatus(idcard);
            if (amount > 0) {
                return error(-1, "该居民已签约了家庭医生！");
            }
            if (StringUtils.isNotEmpty(images)) {
                images = CommonUtil.copyTempImage(images);
            }
            Patient patient = patientService.findByMobile(mobile);
            if (patient != null && !StringUtils.equals(patient.getIdcard(), idcard)) {
                return error(-1, "该手机号已绑定其他身份证号！");
            }
            Doctor cDoctor = doctorService.findDoctorByCode(getUID());
            SignFamily sf = familyContractService.agent(getAccessToken(), name, doctor, doctorName,
                    healthDoctor, healthDoctorName, majorDoctor, majorDoctorName, cDoctor.getHospital(), cDoctor.getHosptialName(),
                    idcard, ssc, mobile, emerMobile, images, disease, expenses, signDoctorCode, signDoctorName, signDoctorLevel, group);

            if (sf == null) {
                return error(-1, "代理签约失败！");
            } else {
                return success("代理签约成功！");
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "代理签约失败！");
        }
    }

    /**
     * 患者签约申请处理接口
     *
     * @param signType         是否有三师签约 1 否 2是
     * @param healthDoctor     健康管理师标识
     * @param healthDoctorName 健康管理师姓名
     * @param majorDoctor      专科医生标识
     * @param disease          疾病code
     * @param msgid            消息id
     * @param patientIDcard    患者身份证
     * @param type             处理类型：1同意，2拒绝
     * @param group
     * @return
     */
    @RequestMapping(value = "sign")
    @ResponseBody
    public String sign(
            @RequestParam(required = true, defaultValue = "1") String signType,
            String healthDoctor,
            @RequestParam(required = false, defaultValue = "1") String disease,
            String healthDoctorName,
            @RequestParam(required = false) String majorDoctor,
            @RequestParam(required = false) String majorDoctorName,
            long msgid,
            String patientIDcard,
            int type, String group,
            @RequestParam(required = false, defaultValue = "0") String expenses) {
        try {
            try {
                String checkUrl = SystemConf.getInstance().getSystemProperties().getProperty("sign_check_upload");
                String jsonString = HttpUtil.sendPost(checkUrl + "/third/sign/CheckSignFamily?idcard=" + patientIDcard, "");

                if (!StringUtils.isEmpty(jsonString)) {
                    JSONObject checkJson = new JSONObject(jsonString);

                    if (checkJson.getInt("status") == 200) {
                        JSONObject jsonData = checkJson.getJSONObject("data");

                        if (jsonData.getString("status").equals("1")) {
                            return error(-1, "此身份证号已签约");
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }


            int res = familyContractService.handleSign(signType, getAccessToken(), healthDoctor, healthDoctorName, msgid, patientIDcard, type, disease, majorDoctor, majorDoctorName, group, expenses);
            if (res == -1) {
                return error(-1, "未知的处理类型！");
            } else if (res == 0) {
                return error(-1, "操作失败或签约状态已变更！");
            } else {
                if (type == 1) {
                    return success("已同意患者签约！");
                } else if (type == 2) {
                    return success("已拒绝患者签约！");
                } else {
                    return error(-1, "未知的处理类型！");
                }
            }
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * @param patientCode 患者code
     * @return
     */
    @RequestMapping(value = "getSanshiSign")
    @ResponseBody
    public String getSanshiSign(
            String patientCode) {
        try {
            Map<String, Object> res = familyContractService.getSanshiSignByPatientCode(patientCode);

            return write(200, "获取消息列表成功！", "data", res);
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * 患者解约申请处理接口
     *
     * @param msgid   消息id
     * @param patient 患者标识
     * @param type    处理类型：1同意，2拒绝
     * @param reason  解约原因
     * @return
     */
    @RequestMapping(value = "surrender")
    @ResponseBody
    public String surrender(
            long msgid,
            String patient,
            int type,
            @RequestParam(required = false) String reason) {
        try {
            int res = familyContractService.handleSurrender(getAccessToken(), msgid, patient, type, reason);
            if (res == -1) {
                return error(-1, "未知的处理类型！");
            } else if (res == 0) {
                return error(-1, "操作失败或签约状态已变更！");
            } else if (res == 1) {
                if (type == 1) {
                    return success("解约已生效！");
                } else {
                    return success("已拒绝患者解约申请！");
                }
            }
            return error(-1, "操作失败！");
        } catch (Exception e) {
            error(e);
            return error(-1, "操作失败！");
        }
    }

    /**
     * 查询患者相关的签约消息
     *
     * @return
     */
    @RequestMapping(value = "messages")
    @ResponseBody
    public String messages(long id, int pagesize) {
        try {
            JSONArray array = new JSONArray();
            Page<Message> list = familyContractService.findMessageByDoctor(getUID(), id, pagesize);
            if (list != null) {
                for (Message msg : list) {
                    if (msg == null) {
                        continue;
                    }
                    JSONObject json = new JSONObject();
                    // 消息ID
                    json.put("id", msg.getId());
                    // 消息标题
                    json.put("title", msg.getTitle());
                    // 消息内容
                    json.put("message", msg.getContent());
                    // 签约code
                    json.put("signCode", StringUtils.isEmpty(msg.getData())?"":msg.getData());
                    // 消息类型
                    json.put("type", msg.getType());
                    // 发送人标识
                    json.put("sender", msg.getSender());
                    // 发送人姓名
                    json.put("senderName", msg.getSenderName());
                    // 发送人头像
                    json.put("senderPhoto", msg.getSenderPhoto());
                    // 是否已读：1未读，0已读
                    json.put("read", msg.getRead());
                    // 是否已处理，1为未处理，0为已处理
                    json.put("status", msg.getOver());
                    // 是否已处理，1为签约处理，4解约处理
                    json.put("signStatus", msg.getSignStatus());
                    // 解约理由
                    json.put("reason", msg.getReason());
                    // 解约理由
                    json.put("sex", msg.getSex());
                    // 发送时间
                    json.put("czrq", DateUtil.dateToStrLong(msg.getCzrq()));
                    array.put(json);
                }
            }
            return write(200, "获取消息列表成功！", "list", array);
        } catch (Exception e) {
            error(e);
            return error(-1, "获取消息列表失败！");
        }
    }

    public static void main(String[] args) {
        String idcard = "350628198711215041";
        IdcardInfoExtractor ie = new IdcardInfoExtractor(idcard);
        System.out.println(ie.toString());
        // 校验身份证号
        IdcardValidator validator = new IdcardValidator();
        if (validator.isValidatedAllIdcard(idcard)) {
            if (idcard.length() == 15) {
                idcard = validator.convertIdcarBy15bit(idcard);
            }
        } else {
            System.out.println("请输入正确的身份证号！");
        }
        if (StringUtils.isEmpty(idcard)) {
            System.out.println("请输入正确的身份证号！");
        }
    }

    /**
     * 判断身份证是否存在
     *
     * @return
     */
    @RequestMapping(value = "checkMoblie")
    @ResponseBody
    public String checkMoblie(String mobile) {
        try {
            JSONObject json = new JSONObject();
            SignFamily signFamily = familyContractService.getFamilyContractByMobile(mobile);
            if (signFamily == null) {
                json.put("islive", "true");
            } else {
                json.put("islive", "false");
            }
            return write(200, "验证成功！", "data", json);
        } catch (Exception e) {
            error(e);
            return error(-1, "获取消息列表失败！");
        }
    }

    /**
     * 获取病人的三师签约信息
     *
     * @param idCard
     * @return
     */
    @RequestMapping(value = "patient_sanshi_signinfo")
    @ResponseBody
    public String getPatientSanshiSignByIdCard(String idCard) {
        try {
            if (StringUtils.isEmpty(idCard)) {
                return error(-1, "请输入身份证号!");
            }

            JSONObject result = new JSONObject();

            try {
                String checkUrl = SystemConf.getInstance().getSystemProperties().getProperty("sign_check_upload");
                String jsonString = HttpUtil.sendPost(checkUrl + "/third/sign/CheckSignFamily?idcard=" + idCard, "");

                if (!StringUtils.isEmpty(jsonString)) {
                    JSONObject checkJson = new JSONObject(jsonString);
                    if (checkJson.getInt("status") == 200) {
                        JSONObject jsonData = checkJson.getJSONObject("data");

                        if (jsonData.getString("status").equals("1")) {
                            result.put("signStatus", "2");
                            result.put("msg", "病人已申请过家庭签约!");
                            return write(200, "查询成功！", "data", result);
                        }
                    }
                }
            }catch (Exception e){
                e.printStackTrace();
            }

            result = familyContractService.getSanshiSingInfoByPatientIdCard(idCard);

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

    /**
     * 更新患者签约补贴类型
     *
     * @param expensesType 补贴类型
     * @param patient      患者
     * @return
     */
    @RequestMapping(value = "/expenses_type_update")
    @ResponseBody
    public String updateExpensesType(String expensesType, String patient) {
        try {
            if (StringUtils.isEmpty(expensesType)) {
                return error(-1, "补贴类型不能为空");
            }
            if (StringUtils.isEmpty(patient)) {
                return error(-1, "患者不能为空");
            }

            SignFamily familySign = familyContractService.findByPatient(patient);

            if (familySign == null) {
                return error(-1, "居民家庭签约不存在");
            } else {
                if (StringUtils.isNotEmpty(familySign.getMedicalInsuranceNum())) {
                    return error(-1, "数据已上传社保，不能修改补贴类型");
                }
            }

            if (familyContractService.updateExpensesType(expensesType, patient)) {
                return write(200, "更新成功");
            } else {
                return write(-1, "不存在该患者签约");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "更新失败");
        }
    }

    /**
     * 查询待签约患者数据
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/patient_signing")
    @ResponseBody
    public String getSigningPatientInfo(String patient) {
        try {
            Patient temp = patientInfoService.findByCode(patient);
            if (temp != null) {
                JSONObject json = new JSONObject();
                // 设置患者标识
                json.put("code", temp.getCode());
                // 设置患者姓名
                json.put("name", temp.getName());
                // 设置患者头像
                json.put("photo", CommonUtil.getPhoneUrl(temp.getPhoto()));
                // 设置患者年龄
                json.put("age", DateUtil.getAgeByBirthday(temp.getBirthday()));
                // 设置患者性别
                json.put("sex", temp.getSex());
                // 设置患者病情：0绿标，1黄标，2红标
                json.put("diseaseLevel", temp.getDiseaseCondition());
                // 设置患者身份证号
                json.put("idCard", temp.getIdcard());
                // 设置患者出生年月
                json.put("birthday", DateUtil.dateToStr(temp.getBirthday(), DateUtil.YYYY_MM_DD));
                // 设置患者手机号码
                json.put("mobile", temp.getMobile());
                // 设置患者联系电话
                json.put("phone", temp.getPhone());
                // 设置患者居住省份
                json.put("provinceName", temp.getProvinceName());
                json.put("cityName", temp.getCityName());
                json.put("townName", temp.getTownName());
                json.put("streetName", temp.getStreetName());
                // 设置患者地址
                json.put("address", temp.getAddress());
                //设置患者医保号
                json.put("ssc", temp.getSsc());

                String diseases = redisTemplate.opsForValue().get("disease:" + patient);
                if (!StringUtils.isEmpty(diseases)) {
                    json.put("diseases", new JSONArray(diseases));
                } else {
                    json.put("diseases", "");
                }

                SignFamily jtSign = familyContractService.findSigningByPatient(patient);

                // 家庭签约
                if (jtSign != null) {
                    json.put("applySurrDate", jtSign.getPatientApplyUnsignDate());
                    json.put("applyDate", jtSign.getPatientApplyDate());
                    json.put("jtSign", new JSONObject(jtSign));
                } else {
                    throw new Exception("未找到患者待家庭签约的数据");
                }

                return write(200, "患者信息查询成功！", "data", json);
            } else {
                return error(-1, "患者信息查询失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
            return error(-1, "患者信息查询失败");
        }
    }

    /**
     * 获取家庭签约社保流水号
     *
     * @param patient
     * @return
     */
    @RequestMapping(value = "/medical_insurance_num")
    @ResponseBody
    public String getMedicalInsuranceNum(String patient) {
        try {
            JSONObject json = new JSONObject();
            SignFamily familySign = familyContractService.findByPatient(patient);

            if (familySign != null) {
                if (StringUtils.isNotEmpty(familySign.getMedicalInsuranceNum())) {
                    json.put("status", 1); // 已上传社保
                    json.put("medicalInsuranceNum", familySign.getMedicalInsuranceNum());
                } else {
                    json.put("status", 0);
                    json.put("medicalInsuranceNum", "");
                }
            } else {
                json.put("status", -1); // 没有家庭签约
                json.put("medicalInsuranceNum", "");
            }

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

    /**
     * 获取签约数据
     *
     * @param code 签约code
     * @return
     */
    @RequestMapping(value = "/family_sign")
    @ResponseBody
    public String getSignFamily(String code){
        try{
            if(StringUtils.isEmpty(code)){
                return error(-1,"参数不能为空");
            }
            SignFamily signFamily = familyContractService.findSignFamilyByCode(code);

            if(signFamily == null){
                return error(-1,"签约数据不存在");
            }

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