package thyyxxk.webserver.service.zhuyuanyisheng.emr;

import cn.hutool.core.date.format.FastDateFormat;
import cn.hutool.core.text.StrFormatter;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.config.envionment.JcptMobile;
import thyyxxk.webserver.config.exception.BizException;
import thyyxxk.webserver.config.exception.ExceptionEnum;
import thyyxxk.webserver.dao.his.zhuyuanyisheng.emr.EmrControlDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.zhuyuanyisheng.emr.EmrLimitUnlock;
import thyyxxk.webserver.entity.zhuyuanyisheng.emrcontrolrule.*;
import thyyxxk.webserver.service.PublicServer;
import thyyxxk.webserver.service.hutoolcache.ExtraCache;
import thyyxxk.webserver.service.jcptmobile.JcptMobileService;
import thyyxxk.webserver.utils.*;

import javax.servlet.http.HttpServletResponse;
import java.util.*;

/**
 * @author Administrator
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class EmrControlRuleSever {
    private final EmrControlDao dao;
    private final PublicServer publicServer;
    private final JcptMobileService mobileService;
    private final ExtraCache extraCache;
    private final JcptMobile jcptMobile;


    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> requestToUnlockMedicalRecords(EmrLimitUnlock param) {
        param.setApplicant(TokenUtil.getInstance().getTokenUserId());
        param.setApplicationTime(new Date());
        log.info("数据:{}", JSON.toJSONString(param));

        // 把原来地申请取消
        int count = dao.updateUnlockOld(param);
        String str = "申请成功，等待医务部审核。";
        if (count > 0) {
            str = "原申请已顶替，申请成功，等待医务部审核。";
        }
        int insert = dao.applicationUnlock(param);
        if (insert == 0) {
            throw new BizException(ExceptionEnum.ERROR_MESSAGE, "申请错误。");
        }
        try {
            sendWxMessage(param);
        } catch (Exception ignored) {
        }
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE, str);
    }

    public void sendWxMessage(EmrLimitUnlock param) {
        if (jcptMobile.getUrl() == null) {
            return;
        }

        String data = extraCache.getValue("医务部编码", () -> {
            List<String> yiWuBuUser = dao.getYiWuBuUser();
            return String.join("|", yiWuBuUser);
        });

        String date = FastDateFormat.getInstance("yyyy年MM月dd日 HH时mm分")
                .format(param.getApplicationTime());

        String description = StrFormatter.format("<div class=\"gray\">{}</div> <div class=\"normal\">理由:{}</div><div class=\"highlight\">解锁：【{}】</div>", date, param.getRequestRemarks(), param.getUnlockJson());
        JSONObject js = getMessageJson(data, description);

        mobileService.post("/wecom/sendMsg")
                .addBody(js)
                .execute();
    }

    private @NotNull JSONObject getMessageJson(String data, String description) {
        String url = StrUtil.format("{}?appid={}&redirect_uri={}/login?page=unlockemr&response_type=code&scope=snsapi_privateinfo&state=STATE&agentid={}#wechat_redirect",
                jcptMobile.getUrl(),
                jcptMobile.getAppid(),
                jcptMobile.getAddress(),
                jcptMobile.getAgentid()
        );
        return new JSONObject() {{
            put("touser", data);
            put("msgtype", "textcard");
            put("enable_id_trans", 0);
            put("enable_duplicate_check", 0);
            put("duplicate_check_interval", 1800);
            put("textcard", new JSONObject() {{
                put("title", "申请解锁病历");
                put("btntxt", "前往");
                put("description", description);
                put("url", url);
            }});
        }};
    }

    public ResultVo<IPage<EmrLimitUnlock>> getApplicationData(SelectUnlockParam param) {
        if (publicServer.noNeedRule(38)) {
            return ResultVoUtil.fail(ExceptionEnum.NO_PERMISSION_TO_VIEW);
        }
        IPage<EmrLimitUnlock> iPage = new Page<>(param.getCurrentPage(), param.getPageSize(), param.getTotal() == 0);
        QueryWrapper<EmrLimitUnlock> qw = getEmrLimitUnlockQueryWrapper(param);
        iPage.setTotal(param.getTotal());
        return ResultVoUtil.success(dao.selectUnlock(iPage, qw));
    }

    @NotNull
    private static QueryWrapper<EmrLimitUnlock> getEmrLimitUnlockQueryWrapper(SelectUnlockParam param) {
        QueryWrapper<EmrLimitUnlock> qw = new QueryWrapper<>();
        if (ListUtil.notBlank(param.getDateRange())) {
            qw.ge("application_time", param.getDateRange().get(0));
            qw.lt("application_time", param.getDateRange().get(1));
        }
        if (param.getFlag() > -1) {
            qw.eq("state", param.getFlag());
        }
        return qw;
    }

    public void exportExcelUnlock(HttpServletResponse response, SelectUnlockParam param) {
        IPage<EmrLimitUnlock> iPage = new Page<>(param.getCurrentPage(), -1, false);
        QueryWrapper<EmrLimitUnlock> qw = getEmrLimitUnlockQueryWrapper(param);
        iPage = dao.selectUnlock(iPage, qw);
        if (ListUtil.isBlank(iPage.getRecords())) {
            return;
        }

        String[] title = {"住院号", "住院次数", "申请人", "申请时间", "申请权限", "申请编辑时间", "申请备注", "状态", "审核人", "审核时间", "审核备注"};
        String[][] content = new String[iPage.getRecords().size()][];
        for (int i = 0; i < iPage.getRecords().size(); i++) {
            content[i] = new String[title.length];
            EmrLimitUnlock index = iPage.getRecords().get(i);
            content[i][0] = index.getPatNo();
            content[i][1] = String.valueOf(index.getTimes());
            content[i][2] = index.getApplicantName();
            content[i][3] = DateUtil.formatDatetime(index.getApplicationTime());
            content[i][4] = index.getUnlockJson();
            content[i][5] = DateUtil.formatDatetime(index.getEffectiveTime());
            content[i][6] = index.getRequestRemarks();
            content[i][7] = index.getStateName();
            content[i][8] = index.getApproveName();
            content[i][9] = DateUtil.formatDatetime(index.getReviewTime());
            content[i][10] = index.getReviewNotes();
        }
        ExcelUtil.exportExcel(response, title, content);
        log.info("数据：{}", JSON.toJSONString(iPage));
    }

    public ResultVo<String> reviewMedicalRecordsToUnlock(EmrLimitUnlock param) {
        if (publicServer.noNeedRule(38)) {
            return ResultVoUtil.fail(ExceptionEnum.UNAUTHORIZED_OPERATION);
        }
        EmrLimitUnlock emrLimitUnlock = dao.selectUnlockById(param.getId());
        if (emrLimitUnlock.getState().equals(3)) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "该数据已经被申请人删除了，无法审核。");
        }
        if (emrLimitUnlock.getState().equals(param.getState())) {
            return ResultVoUtil.fail(ExceptionEnum.LOGICAL_ERROR, "请勿重复操作。");
        }
        param.setApprove(TokenUtil.getInstance().getTokenUserId());
        dao.updateUnlockByIdNew(param);
        log.info("电子病历质控审核：{}", JSON.toJSONString(param));
        return ResultVoUtil.success(ExceptionEnum.SUCCESS_AND_EL_MESSAGE);
    }

    public ResultVo<EmrLimitUnlock> getMyUnlockByPatNo(String patNo, Integer times) {
        return ResultVoUtil.success(dao.selectMyUnlockReqByPatNo(patNo, times, TokenUtil.getInstance().getTokenUserId()));
    }

}
