package com.docus.server.collection.service.impl;

import cn.hutool.core.util.NumberUtil;
import com.docus.core.util.DateUtil;
import com.docus.core.util.Func;
import com.docus.infrastructure.core.exception.BaseException;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.collection.dto.TBasicDto;
import com.docus.server.collection.entity.TBasic;
import com.docus.server.collection.entity.TBasicExtend;
import com.docus.server.collection.mapper.TBasicMapper;
import com.docus.server.collection.service.ITBasicService;
import com.docus.server.report.entity.MaternalInfantRelationship;
import com.docus.server.rpc.SdRyHospitalRpc;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.Objects;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * @BelongsProject: docus-webservice-sdry
 * @BelongsPackage: com.docus.server.collection.service.impl
 * @Author: chierhao
 * @CreateTime: 2023-02-28  08:37
 * @Description: TODO
 * @Version: 1.0
 */
@Service
@Slf4j
public class TBasicServiceImpl implements ITBasicService {

    @Resource
    private TBasicMapper tBasicMapper;

    @Resource
    private IdService idService;

    @Resource
    private SdRyHospitalRpc sdRyHospitalRpc;

    @Resource
    private ThreadPoolExecutor threadPoolExecutor;

    @Override
    @Transactional
    public void setTBasic(TBasicDto tBasicDto) throws Exception {
        //判断jzh是否重复
        Integer num = tBasicMapper.selectOne(tBasicDto.getJzh());
        if (num > 0) {
            updateTBasic(tBasicDto);
            return;
        }
        Long patientId = idService.getDateSeq();

        //数据类型转化，格式处理
        Date admissDate = null;
        if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
            admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        Date disDate = null;
        if (Func.isNotEmpty(tBasicDto.getDisDate())) {
            disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        String admissTimesStr = tBasicDto.getAdmissTimes();
        Integer admissTimes = null;
        if (NumberUtil.isInteger(admissTimesStr)) {
            admissTimes = Integer.parseInt(admissTimesStr);
        }
        String ageStr = tBasicDto.getAge();
        if (Func.isNotEmpty(ageStr)) {
            ageStr = ageStr.substring(0, ageStr.length() - 1);
        }
        Integer age = null;
        if (NumberUtil.isInteger(ageStr)) {
            age = Integer.parseInt(ageStr);
        }
        String sexName = tBasicDto.getSexName();
        if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
            sexName = sexName.substring(0, 1);
        }
        String admissDaysStr = tBasicDto.getAdmissDays();
        Integer admissDays = null;
        if (NumberUtil.isInteger(admissDaysStr)) {
            admissDays = Integer.parseInt(admissDaysStr);
        }
        String isDeadStr = tBasicDto.getIsDead();
        Integer isDead = 0;
        if ("死亡".equals(isDeadStr)) {
            isDead = 1;
        }

        //组装数据
        TBasic tBasic = new TBasic();
        tBasic.setPatientId(patientId.toString());
        tBasic.setJzh(tBasicDto.getJzh());
        tBasic.setInpatientNo(tBasicDto.getInpatientNo());
        tBasic.setAdmissTimes(admissTimes);
        tBasic.setName(tBasicDto.getName());
        tBasic.setAdmissDate(admissDate);
        tBasic.setDisDate(disDate);
        tBasic.setAdmissDept(tBasicDto.getAdmissDept());
        tBasic.setAdmissDeptName(tBasicDto.getAdmissDeptName());
        tBasic.setDisDeptName(tBasicDto.getDisDeptName());
        tBasic.setAttending(tBasicDto.getAttending());
        tBasic.setAttendingName(tBasicDto.getAttendingName());
        tBasic.setAge(age);
        tBasic.setSex(tBasicDto.getSex());
        tBasic.setIdCard(tBasicDto.getIdCard());
        tBasic.setDisDept(tBasicDto.getDisDept());
        tBasic.setSexName(sexName);
        tBasic.setBedNum(tBasicDto.getBedNum());
        tBasic.setAdmissDays(admissDays);
        tBasic.setIsDead(isDead);
        tBasic.setWardCode(tBasicDto.getWardCode());
        tBasic.setWardName(tBasicDto.getWardName());

        //设置是否婴儿
        String inpatientNo = tBasicDto.getInpatientNo();
        if (inpatientNo.contains("B") || inpatientNo.contains("b")) {
            tBasic.setIsOther(1);
        } else {
            tBasic.setIsOther(0);
        }
        String sdryIndex = tBasicDto.getSdryIndex();
        TBasicExtend tBasicExtend = new TBasicExtend();
        tBasicExtend.setPatientId(patientId.toString());
        tBasicExtend.setWardCode(tBasicDto.getWardCode());
        tBasicExtend.setWardName(tBasicDto.getWardName());
        tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));
        //持久化
        tBasicMapper.insert(tBasic);
        tBasicMapper.insertExtend(tBasicExtend);
        confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
    }


    @Override
    @Transactional
    public void updateTBasic(TBasicDto tBasicDto) throws Exception {
        //判断jzh是否存在
        String patientId = tBasicMapper.getPatientId(tBasicDto.getJzh());
        if (Func.isEmpty(patientId)) {
            setTBasic(tBasicDto);
            return;
        }
        //数据类型转化，格式处理
        Date admissDate = null;
        if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
            admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        Date disDate = null;
        if (Func.isNotEmpty(tBasicDto.getDisDate())) {
            disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        String admissTimesStr = tBasicDto.getAdmissTimes();
        Integer admissTimes = null;
        if (NumberUtil.isInteger(admissTimesStr)) {
            admissTimes = Integer.parseInt(admissTimesStr);
        }
        String ageStr = tBasicDto.getAge();
        if (Func.isNotEmpty(ageStr)) {
            ageStr = ageStr.substring(0, ageStr.length() - 1);
        }
        Integer age = null;
        if (NumberUtil.isInteger(ageStr)) {
            age = Integer.parseInt(ageStr);
        }
        String sexName = tBasicDto.getSexName();
        if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
            sexName = sexName.substring(0, 1);
        }
        String admissDaysStr = tBasicDto.getAdmissDays();
        Integer admissDays = null;
        if (NumberUtil.isInteger(admissDaysStr)) {
            admissDays = Integer.parseInt(admissDaysStr);
        }
        String isDeadStr = tBasicDto.getIsDead();
        Integer isDead = 0;
        if ("死亡".equals(isDeadStr)) {
            isDead = 1;
        }

        //组装数据
        TBasic tBasic = new TBasic();

        tBasic.setJzh(tBasicDto.getJzh());
        tBasic.setPatientId(patientId);
        tBasic.setInpatientNo(tBasicDto.getInpatientNo());
        tBasic.setAdmissTimes(admissTimes);
        tBasic.setName(tBasicDto.getName());
        tBasic.setAdmissDate(admissDate);
        tBasic.setDisDate(disDate);
        tBasic.setAdmissDept(tBasicDto.getAdmissDept());
        tBasic.setAdmissDeptName(tBasicDto.getAdmissDeptName());
        tBasic.setDisDeptName(tBasicDto.getDisDeptName());
        tBasic.setAttending(tBasicDto.getAttending());
        tBasic.setAttendingName(tBasicDto.getAttendingName());
        tBasic.setAge(age);
        tBasic.setSex(tBasicDto.getSex());
        tBasic.setIdCard(tBasicDto.getIdCard());
        tBasic.setDisDept(tBasicDto.getDisDept());
        tBasic.setSexName(sexName);
        tBasic.setBedNum(tBasicDto.getBedNum());
        tBasic.setAdmissDays(admissDays);
        tBasic.setIsDead(isDead);
        tBasic.setWardCode(tBasicDto.getWardCode());
        tBasic.setWardName(tBasicDto.getWardName());
        tBasic.setIsOther(tBasicDto.getIsOther());
        //设置是否婴儿
        String inpatientNo = tBasicDto.getInpatientNo();
        if (tBasic.getIsOther() == 0 && (inpatientNo.contains("B") || inpatientNo.contains("b"))) {
            tBasic.setIsOther(1);
        } else if (tBasic.getIsOther() == 0) {
            tBasic.setIsOther(0);
        }
        //是否取消住院
        if ("2".equals(tBasicDto.getStatu())) {
            tBasic.setDisDate(null);
        }
        String sdryIndex = tBasicDto.getSdryIndex();
        TBasicExtend tBasicExtend = new TBasicExtend();
        tBasicExtend.setPatientId(patientId);
        tBasicExtend.setWardCode(tBasicDto.getWardCode());
        tBasicExtend.setWardName(tBasicDto.getWardName());
        tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));

        //持久化
        tBasicMapper.update(tBasic);
        tBasicMapper.updateExtend(tBasicExtend);
        confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
    }

    @Override
    @Transactional
    public void updateAdmissTBasic(TBasicDto tBasicDto) throws Exception {
        //判断jzh是否存在
        String patientId = tBasicMapper.getPatientId(tBasicDto.getJzh());
        if (Func.isEmpty(patientId)) {
            throw new BaseException("数据不存在，更新失败");
        }
        if ("2".equals(tBasicDto.getStatu())) {
            tBasicMapper.deleteByPatientId(patientId);
            log.info("入院信息删除jzh:{},patientId:{},statusCode:{}", tBasicDto.getJzh(), patientId, tBasicDto.getStatu());
            return;
        }
        //数据类型转化，格式处理
        Date admissDate = null;
        if (Func.isNotEmpty(tBasicDto.getAdmissDate())) {
            admissDate = Func.parseDate(tBasicDto.getAdmissDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        Date disDate = null;
        if (Func.isNotEmpty(tBasicDto.getDisDate())) {
            disDate = Func.parseDate(tBasicDto.getDisDate(), DateUtil.PATTERN_DATETIME_MINI);
        }
        String admissTimesStr = tBasicDto.getAdmissTimes();
        Integer admissTimes = null;
        if (NumberUtil.isInteger(admissTimesStr)) {
            admissTimes = Integer.parseInt(admissTimesStr);
        }
        String ageStr = tBasicDto.getAge();
        if (Func.isNotEmpty(ageStr)) {
            ageStr = ageStr.substring(0, ageStr.length() - 1);
        }
        Integer age = null;
        if (NumberUtil.isInteger(ageStr)) {
            age = Integer.parseInt(ageStr);
        }
        String sexName = tBasicDto.getSexName();
        if (Func.isNotEmpty(sexName) && sexName.length() > 1) {
            sexName = sexName.substring(0, 1);
        }
        String admissDaysStr = tBasicDto.getAdmissDays();
        Integer admissDays = null;
        if (NumberUtil.isInteger(admissDaysStr)) {
            admissDays = Integer.parseInt(admissDaysStr);
        }
        String isDeadStr = tBasicDto.getIsDead();
        Integer isDead = 0;
        if ("死亡".equals(isDeadStr)) {
            isDead = 1;
        }

        //组装数据
        TBasic tBasic = new TBasic();

        tBasic.setJzh(tBasicDto.getJzh());
        tBasic.setPatientId(patientId);
        tBasic.setInpatientNo(tBasicDto.getInpatientNo());
        tBasic.setAdmissTimes(admissTimes);
        tBasic.setName(tBasicDto.getName());
        tBasic.setAdmissDate(admissDate);
        tBasic.setDisDate(disDate);
        tBasic.setAdmissDept(tBasicDto.getAdmissDept());
        tBasic.setAdmissDeptName(tBasicDto.getAdmissDeptName());
        tBasic.setDisDeptName(tBasicDto.getDisDeptName());
        tBasic.setAttending(tBasicDto.getAttending());
        tBasic.setAttendingName(tBasicDto.getAttendingName());
        tBasic.setAge(age);
        tBasic.setSex(tBasicDto.getSex());
        tBasic.setIdCard(tBasicDto.getIdCard());
        tBasic.setDisDept(tBasicDto.getDisDept());
        tBasic.setSexName(sexName);
        tBasic.setBedNum(tBasicDto.getBedNum());
        tBasic.setAdmissDays(admissDays);
        tBasic.setIsDead(isDead);
        tBasic.setWardCode(tBasicDto.getWardCode());
        tBasic.setWardName(tBasicDto.getWardName());
        tBasic.setIsOther(tBasicDto.getIsOther());
        //设置是否婴儿
        String inpatientNo = tBasicDto.getInpatientNo();
        if (tBasic.getIsOther() == 0 && (inpatientNo.contains("B") || inpatientNo.contains("b"))) {
            tBasic.setIsOther(1);
        } else if (tBasic.getIsOther() == 0) {
            tBasic.setIsOther(0);
        }
        String sdryIndex = tBasicDto.getSdryIndex();
        TBasicExtend tBasicExtend = new TBasicExtend();
        tBasicExtend.setPatientId(patientId);
        tBasicExtend.setWardCode(tBasicDto.getWardCode());
        tBasicExtend.setWardName(tBasicDto.getWardName());
        tBasicExtend.setSdryIndex(sdryIndex == null ? null : sdryIndex.replace("z", "").replace("m", ""));

        //持久化
        tBasicMapper.update(tBasic);
        tBasicMapper.updateExtend(tBasicExtend);
        confirmAndUpdIcuRecordState(tBasic.getInpatientNo(), tBasic.getAdmissTimes());
    }


    @Override
    public TBasic getSdRyParentPatientInfo(String babyPatientId) {
        // 宝宝索引
        String babyIndex = tBasicMapper.getSdRyIndex(babyPatientId);
        if (Func.isBlank(babyIndex)) {
            return null;
        }
        // 宝宝索引查妈妈索引 和住院次数
        MaternalInfantRelationship infantRelationship = tBasicMapper.getMaternalInfantRelationship(babyIndex);

        if (Objects.isNull(infantRelationship) || Func.isBlank(infantRelationship.getMomId()) ) {
            return null;
        }
        String parentSdRyIndex=infantRelationship.getMomId();
        // 通过索引和住院次数查病案主键
        String parentPatientId = tBasicMapper.getPatientIdBySdRyIndexAndAdmissTimes(parentSdRyIndex,infantRelationship.getParentTimes());
        if (Func.isBlank(parentPatientId)) {
            return null;
        }
        // 通过病案主键查基础信息
        return tBasicMapper.getByPatientId(parentPatientId);
    }

    @Override
    public boolean getIsBabyBasic(String patientId) {
        TBasic tBasic = tBasicMapper.getByPatientId(patientId);
        return Func.isNotEmpty(tBasic) && Func.isNotBlank(tBasic.getInpatientNo()) && tBasic.getInpatientNo().toUpperCase().contains("B");
    }


    public void confirmAndUpdIcuRecordState(String inpatientNo, Integer admissTimes) {
        threadPoolExecutor.execute(() -> {
            // 此处异步，睡眠一秒保证事务提交
            try {
                TimeUnit.SECONDS.sleep(1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            sdRyHospitalRpc.confirmAndUpdIcuRecordState(inpatientNo, admissTimes);
        });
    }
}


