package thyyxxk.webserver.service.executeItem;

import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import thyyxxk.webserver.dao.his.executeItem.GenerateYzDao;
import thyyxxk.webserver.dao.his.executeItem.YzActOccDao;
import thyyxxk.webserver.dao.his.executeItem.YzYpZyOrderDao;
import thyyxxk.webserver.dao.his.executeItem.YzZyPatientFeeDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.datamodify.YzActOrder;
import thyyxxk.webserver.entity.executeItem.GenerateYzVo;
import thyyxxk.webserver.entity.executeItem.NumberEnum;
import thyyxxk.webserver.entity.executeItem.YzActOcc;
import thyyxxk.webserver.entity.executeItem.YzOrderFrequency;
import thyyxxk.webserver.entity.executeItem.YzYpZyOrder;
import thyyxxk.webserver.entity.executeItem.YzZyPatientFee;
import thyyxxk.webserver.entity.executeItem.ZdChargeItem;
import thyyxxk.webserver.entity.inpatient.ZyActpatient;
import thyyxxk.webserver.utils.AssertUtil;
import thyyxxk.webserver.utils.CommonUtil;
import thyyxxk.webserver.utils.ResultVoUtil;
import thyyxxk.webserver.utils.TokenUtil;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description:
 * @Author:lihong
 * @Date: 2024/1/8
 */
@Service
@Slf4j
public class GenerateYzService {
    @Resource
    private GenerateYzDao dao;
    @Resource
    private YzActOccDao yzActOccDao;
    @Resource
    private YzYpZyOrderDao yzYpZyOrderDao;
    @Resource
    private YzZyPatientFeeDao yzZyPatientFeeDao;

    private static final String prefixWeek = "week";
    private static final String prefixDay = "day";
    private static final String KF = "d";
    private static final String DSY = "i";
    private static Map<String, String> occTypeMap = new HashMap<>();

    static {
        //key drug_flag 医嘱类型 d 西药 i 大输液 z 中成药 o 医嘱 p 手术 h 护理
        //value occ_type  执行类别 o 执行项目 d 口服药 j 注射用药 i 大输液
        occTypeMap.put("d", "d");
        occTypeMap.put("z", "j");
        occTypeMap.put("i", "i");
        occTypeMap.put("o", "o");
        occTypeMap.put("p", "o");
        occTypeMap.put("h", "o");
    }

    public List<ZyActpatient> queryGenerateYzList(String wardCode) {
        AssertUtil.isnotBlank(wardCode, "病室编码不能为空");
        List<ZyActpatient> list = dao.selectGenerateYzList(wardCode);
        CommonUtil.BeanTrim(list);
        return list;
    }

    public ResultVo<String> generateYp(GenerateYzVo param) {
        //这里只查前后两天的
        AssertUtil.isnotBlank(param.getWardCode(), "病室不能为空");
        AssertUtil.isnotBlank(param.getYzDate(), "医嘱时间不能为空");
        AssertUtil.isnotBlank(param.getZyActpatients(), "请选择病人");
        String startTime = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.parseDate(param.getYzDate()), -2)) + " 00:00:00";
        String endTime = DateUtil.formatDate(DateUtil.offsetDay(DateUtil.parseDate(param.getYzDate()), 2)) + " 23:59:59";
        param.setStartTime(startTime);
        param.setEndTime(endTime);
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("dept_code", param.getWardCode());
        queryWrapper.eq("ward_code", param.getWardCode());
        queryWrapper.ge("occ_time", param.getStartTime());
        queryWrapper.ge("occ_time", param.getEndTime());
        List<YzActOcc> yzActOccs = yzActOccDao.selectList(queryWrapper);

        List<YzZyPatientFee> yzZyPatientFees = yzZyPatientFeeDao.selectList(queryWrapper);

        List<YzYpZyOrder> yzYpZyOrders = yzYpZyOrderDao.selectList(queryWrapper);
        //频率
        List<YzOrderFrequency> yzOrderFrequencies = dao.selectYzOrderFrequency();

        dao.selectYpYz(param.getWardCode());


        return ResultVoUtil.success();
    }

    public ResultVo<String> generateZl(GenerateYzVo param) {

        return ResultVoUtil.success();
    }

    /***
     * @description: 获取周的执行时间
     * @author: lihong
     * @date: 2024/1/9 14:47
     * @param: filedName
     * @return: java.lang.String  返回  7 1 2 ... 周几
     **/
    private static String calcWeekFreqOccTime(String filedName) {
        if(!filedName.startsWith(prefixWeek)){
            throw new IllegalArgumentException("周频率字段格式不对["+filedName+"]");
        }
        return StrUtil.removePrefix(filedName, "week");
    }

    /**
     * @description: 获取频率执行时间
     * @author: lihong
     * @date: 2024/1/9 15:02
     * @param: filedName 字段名称  day2400  day130
     * @return: java.lang.String 返回格式 时分秒 HH:mm:ss
     **/
    private static String calcDayOccTime(String filedName) {
        if(!filedName.startsWith(prefixDay)){
            throw new IllegalArgumentException("天频率字段格式不对["+filedName+"]");
        }
        String dayOccTime = StrUtil.removePrefix(filedName, prefixDay);
        if("2400".equals(dayOccTime)){
            return "00:00:00";
        }else if(dayOccTime.length()== Integer.valueOf(NumberEnum.ThREE.getCode())){
            return StrUtil.format("0{}:{}:00",dayOccTime.substring(0,1) ,dayOccTime.substring(1));
        }else if(dayOccTime.length() == Integer.valueOf(NumberEnum.FOUR.getCode())){
            return StrUtil.format("{}:{}:00",dayOccTime.substring(0,2),dayOccTime.substring(2));
        }else {
           log.info("字段:{}不符合格式",filedName);
            throw new IllegalArgumentException("天频率字段格式不对["+filedName+"]");
        }
    }

    /**
     * @description: 转换为医嘱药品数据
     * @author: lihong
     * @date: 2024/1/9 16:53
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzYpZyOrder
     **/
    private static YzYpZyOrder convert2YzYpZyOrder(ZyActpatient zyActpatient,YzActOrder yzActOrder,ZdChargeItem zdChargeItem,Date occTime){
        YzYpZyOrder yzYpZyOrder = YzYpZyOrder.builder()
                .inpatientNo(zyActpatient.getInpatientNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .actOrderNo(yzActOrder.getActOrderNo())
                .alwaysFlag("ONCE".equals(yzActOrder.getFrequCode()) ? "a" : "t" )
                //待定 待核对
                .amount(yzActOrder.getOrderCount())
                .bedNo(zyActpatient.getBedNo())
                .chargeCode(zdChargeItem.getCode())
                //这是时间暂时 写执行时间
                .chargeDate(DateUtil.parseDate(DateUtil.formatDate(occTime)))
                .deptCode(zyActpatient.getDeptCode())
                .drawer(TokenUtil.getInstance().getTokenUserId())
                .drugClass(KF.equals(yzActOrder.getDrugFlag()) || DSY.equals(yzActOrder.getDrugFlag()) ? yzActOrder.getDrugFlag() : "j")
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .name(zyActpatient.getName())
                //默认给1
                .statusFlag("1")
                .wardCode(zyActpatient.getWardCode())
                //待定
                .retprice(zdChargeItem.getChargeAmount())
                .serial(0)
                .groupNo(yzActOrder.getGroupNo())
                .doctorName(yzActOrder.getPhysician())
                //需要计算暂时不给
                .pageClass(null)
                .drugFlag(zdChargeItem.getDrugFlag())
                .occTime(occTime)
                .pageNo(BigDecimal.ZERO)
                //默认给0 待确认
                .paySelf(yzActOrder.getPaySelf())
                .supriceFlag(Convert.toStr(zdChargeItem.getSuppressFlag()))
                .separateFlag(zdChargeItem.getSeparateFlag())
                .zySerialNo(zyActpatient.getZySerialNo())
                .selfFlag("1".equals(zyActpatient.getYbFlag()) ? "0" : "1")
                .build();
        return yzYpZyOrder;
    }

    /**
     * @description: 转换为医嘱执行数据
     * @author: lihong
     * @date: 2024/1/9 16:52
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzActOcc
     **/
    private  static YzActOcc convert2YzActOcc(ZyActpatient zyActpatient,YzActOrder yzActOrder,ZdChargeItem zdChargeItem,Date occTime){
        YzActOcc yzActOcc = YzActOcc.builder()
                .actOrderNo(yzActOrder.getActOrderNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .alwaysFlag("ONCE".equals(yzActOrder.getFrequCode()) ? "a" : "t" )
                .bedNo(zyActpatient.getBedNo())
                .chargeCode(zdChargeItem.getCode())
                .deptCode(zyActpatient.getDeptCode())
                .wardCode(zyActpatient.getWardCode())
                .discription(yzActOrder.getDiscription())
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .inpatientName(zyActpatient.getName())
                .inpatientNo(zyActpatient.getInpatientNo())
                .occName(zdChargeItem.getName())
                .occTime(occTime)
                .occType(Convert.toStr(occTypeMap.get(yzActOrder.getDrugFlag()),"o"))
                .phyName(yzActOrder.getPhysician())
                .parentNo(yzActOrder.getParentNo() == null ? yzActOrder.getActOrderNo() : yzActOrder.getParentNo())
                //待定  有 附加费 啥的
                .specification("00".equals(yzActOrder.getGroupNo()) ? "诊疗项目" : yzActOrder.getActOrderNo().compareTo(BigDecimal.ZERO) < 0 ? "附加费" : yzActOrder.getDrugSpecification())
                .occOper(TokenUtil.getInstance().getTokenUserId())
                //这个没啥用随便给
                .parentSort(yzActOrder.getParentNo() == null ? Convert.toStr(yzActOrder.getActOrderNo())+"." : Convert.toStr(yzActOrder.getParentNo())+"."+DateUtil.format(new Date(), DatePattern.PURE_TIME_PATTERN))
                //待定
                .drugQuan2(yzActOrder.getDrugQuan())
                .execUnit(yzActOrder.getExecUnit())
                .dose(Convert.toStr(yzActOrder.getDose()))
                .pageNo(0)
                .orderName(yzActOrder.getOrderName())
                .paySelf(yzActOrder.getPaySelf())
                .groupNo(yzActOrder.getGroupNo())
                .selfFlag(NumberEnum.ONE.getCode().equals(zyActpatient.getYbFlag()) ? "0" : "1")
                .frequCode(yzActOrder.getFrequCode())
                .retprice(zdChargeItem.getChargeAmount())
                .serial(yzActOrder.getSerial())
                .doseUnit(yzActOrder.getDoseUnit())
                //待计算确定
                .pageClass(null)
                .supplyCode(yzActOrder.getSupplyCode())
                .drugQuan(yzActOrder.getDrugQuan())
                .instruction(yzActOrder.getInstruction())
                .zySerialNo(zyActpatient.getZySerialNo())
                .build();
        return yzActOcc;
    }
    /**
     * @description: 转换为医嘱病人接口数据 收费信息
     * @author: lihong
     * @date: 2024/1/9 16:52
     * @param: zyActpatient
     * @param: yzActOrder
     * @param: occTime
     * @param: zdChargeItem
     * @return: thyyxxk.webserver.entity.executeItem.YzZyPatientFee
     **/
    private static YzZyPatientFee  convert2YzZyPatientFee(ZyActpatient zyActpatient,YzActOrder yzActOrder,ZdChargeItem zdChargeItem,Date occTime){
        YzZyPatientFee yzZyPatientFee = YzZyPatientFee.builder()
                .inpatientNo(zyActpatient.getInpatientNo())
                .admissTimes(zyActpatient.getAdmissTimes())
                .actOrderNo(yzActOrder.getActOrderNo())
                .detailSn(0)
                .chargeCode(zdChargeItem.getCode())
                //待确定
                .chargeDate(DateUtil.parseDate(DateUtil.formatDate(occTime)))
                .chargeFee(zdChargeItem.getChargeAmount())
                //待定
                .chargeStatus("1")
                .infantFlag(zyActpatient.getInpatientNo().contains("$") ? "1" : "0")
                .opIdCode(TokenUtil.getInstance().getTokenUserId())
                .occTime(occTime)
                .deptCode(zyActpatient.getDeptCode())
                .wardCode(zyActpatient.getWardCode())
                .orderCount(yzActOrder.getOrderCount())
                .paySelf(yzActOrder.getPaySelf())
                .execUnit(yzActOrder.getExecUnit())
                .selfFlag(NumberEnum.ONE.getCode().equals(zyActpatient.getYbFlag()) ? "0" : "1")
                .zySerialNo(zyActpatient.getZySerialNo())
                .separateFlag(zdChargeItem.getSeparateFlag())
                .suppressFlag(Convert.toStr(zdChargeItem.getSuppressFlag()))
                .build();
        return yzZyPatientFee;
    }


}
