package thyyxxk.webserver.api.medicallaboratory;

import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import thyyxxk.webserver.api.medicallaboratory.model.PatientType;
import thyyxxk.webserver.config.auth.PassToken;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.api.medicallaboratory.model.Category;
import thyyxxk.webserver.api.medicallaboratory.model.State;
import thyyxxk.webserver.dao.his.api.MedicalLaboratoryDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.service.externalhttp.WxServer;
import thyyxxk.webserver.utils.DateUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.StringUtil;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;

@RestController
@RequestMapping("/medicalLaboratory")
public class MedicalLaboratoryController {
    private final MedicalLaboratoryDao dao;
    private final WxServer wxServer;

    @Autowired
    public MedicalLaboratoryController(MedicalLaboratoryDao dao, WxServer wxServer) {
        this.dao = dao;
        this.wxServer = wxServer;
    }

    @PassToken
    @PostMapping("/notify")
    public ResultVo<String> notify(@RequestBody MedicalLaboratoryState body) {
        if (null == body.getReqTime()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "申请时间不能为空。");
        }
        if (null == body.getReportState()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "报告状态不能为空。");
        }
        if (null == body.getCategory()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "申请类别不能为空。");
        }
        if (null == body.getPatType()) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者类别不能为空。");
        }
        if (StringUtil.isBlank(body.getPatNo())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者门诊id/住院号不能为空。");
        }
        if (StringUtil.isBlank(body.getPatName())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "患者姓名不能为空。");
        }
        if (StringUtil.isBlank(body.getDeptName())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "申请科室名称不能为空。");
        }
        if (StringUtil.isBlank(body.getDoctorName())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "申请医生姓名不能为空。");
        }
        if (StringUtil.isBlank(body.getReportTitle())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "报告标题不能为空。");
        }
        if (body.getReportState() == State.PROCESSING) {
            if (null == body.getTestTime()) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "检查/检验时间不能为空。");
            }
        }
        if (body.getReportState() == State.PUBLISHED) {
            if (StringUtil.isBlank(body.getReportId())) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "报告状态为[发布]时，报告id不能为空。");
            }
            if (null == body.getPublishTime()) {
                return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "报告状态为[发布]时，发布时间不能为空。");
            }
        }
        MedicalLaboratoryState existOne = dao.selectById(body.getReqNo());
        if (null == existOne) {
            body.setCreateTime(new Date());
            dao.insert(body);
        } else {
            dao.updateById(body);
        }
        if (body.getReportState() == State.PUBLISHED) {
            LocalDate pb = body.getPublishTime().toInstant().atZone(ZoneId.systemDefault()).toLocalDate();
            LocalDate now = LocalDate.now();
            long daysBetween = ChronoUnit.DAYS.between(pb, now);
            if (daysBetween <= 15) {
                pushWxMessage(body);
            }
        }
        return ResultVoUtil.success(body.getReqNo());
    }

    private void pushWxMessage(MedicalLaboratoryState body) {
        if (null != body.getPatType() && body.getPatType() == PatientType.INPATIENT) {
            String cardNo = dao.getPatientIdByInpatientNo(body.getPatNo());
            if (StringUtil.isBlank(cardNo)) {
                return;
            }
            body.setPatNo(cardNo);
        }
        String xmLabel = getLabel(body.getCategory());
        String firstData = StrUtil.format("您之前进行的{}项目已生成{}报告，详情如下：", xmLabel, xmLabel);
        String pbtime = DateUtil.formatDate(body.getPublishTime());
        String redirect = "https://staticweb.hnthyy.cn/wxserver/redirect/pathEntry?path=" + getPath(body);
        String msgContent = "{\"touser\":\"\",\"data\":" +
                "{" +
                "\"first\":{\"color\":\"#FF0000\",\"value\":\"" + firstData + "\"}," +
                "\"keyword1\":{\"color\":\"#173177\",\"value\":\"沭阳铭和医院\"}," +
                "\"keyword2\":{\"color\":\"#173177\",\"value\":\"" + body.getPatName() + "\"}," +
                "\"keyword3\":{\"color\":\"#173177\",\"value\":\"" + body.getReportTitle() + "\"}," +
                "\"keyword4\":{\"color\":\"#173177\",\"value\":\"" + pbtime + "\"}," +
                "\"remark\":{\"color\":\"#FF0000\",\"value\":\"感谢您的使用，祝您健康!\"}," +
                "}," +
                "\"template_id\":\"5lfTTP5Iwx4dEwTB9ihhCDWm0PTkMDTzOUQVsyNaM50\"," +
                "\"url\":\"" + redirect + "\"}";

        JSONObject obj = new JSONObject();

        obj.put("cardNo", body.getPatNo());
        obj.put("msgContext", JSON.parseObject(msgContent));
        wxServer.pushWxMessage(obj);
    }

    private String getLabel(Category category) {
        switch (category) {
            case JY:
                return "检验";
            case JC:
                return "检查";
            case XD:
                return "心电";
            case BL:
                return "病理";
        }
        throw new BizException("不合法的项目类型！");
    }

    private String getPath(MedicalLaboratoryState body) {
        String suffix = "_" + body.getPatNo();
        switch (body.getCategory()) {
            case JY:
                return "checkExamIndex" + suffix;
            case JC:
                return "checkTestIndex" + suffix;
            case XD:
                return "checkElectroIndex" + suffix;
            case BL:
                return "checkPathologyIndex" + suffix;
        }
        throw new BizException("不合法的项目类型！");
    }
}
