package cn.hnthyy.thmz.service.impl.his.mz;

import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.entity.MzException;
import cn.hnthyy.thmz.entity.his.YpBaseYf;
import cn.hnthyy.thmz.entity.his.YpMzFytj;
import cn.hnthyy.thmz.entity.his.mz.Employee;
import cn.hnthyy.thmz.entity.his.mz.MzChargeDetail;
import cn.hnthyy.thmz.entity.thmz.RadSendRecord;
import cn.hnthyy.thmz.entity.thmz.User;
import cn.hnthyy.thmz.mapper.his.YpBaseYfMapper;
import cn.hnthyy.thmz.mapper.his.YpZdDictMapper;
import cn.hnthyy.thmz.mapper.his.YpZdManufactoryMapper;
import cn.hnthyy.thmz.mapper.his.mz.EmployeeMapper;
import cn.hnthyy.thmz.mapper.his.mz.MzChargeDetailMapper;
import cn.hnthyy.thmz.mapper.his.mz.MzPharmacyMapper;
import cn.hnthyy.thmz.service.his.mz.MzPharmacyService;
import cn.hnthyy.thmz.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
@Service
public class MzPharmacyServiceImpl implements MzPharmacyService {

    @Autowired
    private MzPharmacyMapper mzPharmacyMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private YpZdDictMapper ypZdDictMapper;
    @Autowired
    private YpZdManufactoryMapper ypZdManufactoryMapper;
    @Autowired
    private YpBaseYfMapper ypBaseYfMapper;
    @Autowired
    private MzChargeDetailMapper mzChargeDetailMapper;

    @Override
    public List<MzChargeDetail> getMzChargeOrder(ChargeDetailPharmacyVo chargeDetailPharmacyVo) {
        return mzPharmacyMapper.selectMzChargeOrder(chargeDetailPharmacyVo);
    }

    @Override
    public List<YpMzFytjVo> getYpMzRefundFytjPage(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectYpMzRefundFytjPage(chargeFeeParamsVo);
    }

    @Override
    public int getYpMzRefundFytjCount(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectYpMzRefundFytjPageCount(chargeFeeParamsVo);
    }

    @Override
    public List<YpMzFytjVo> getYpMzRefundSucceedFytjPage(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectYpMzRefundSucceedFytjPage(chargeFeeParamsVo);
    }

    @Override
    public int getYpMzRefundSucceedFytjCount(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectYpMzRefundSucceedFytjCount(chargeFeeParamsVo);
    }

    @Override
    public List<Map<String, Object>> getPrescriptionYpMx(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectPrescriptionYpMx(chargeFeeParamsVo);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Map<String, Object> refundMedicineProcessing(List<MzRefundMedicineVo> mzRefundMedicineVos, String userIdCode) {
        Map<String, Object> resultMap = new HashMap<>();
        Date date = new Date();
        int flag = 0;
        for (MzRefundMedicineVo mzRefundMedicineVo : mzRefundMedicineVos) {
            if (StringUtils.isBlank(mzRefundMedicineVo.getPatientId())) {
                resultMap.put("code", -1);
                resultMap.put("message", "病人ID不能为空");
            }
            if (mzRefundMedicineVo.getTimes() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊就诊次数不能为空");
            }
            if (mzRefundMedicineVo.getOrderNo() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "处方号不能为空");
            }
            if (mzRefundMedicineVo.getReceiptNo() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "门诊缴费次数不能为空");
            }
            if (StringUtils.isBlank(mzRefundMedicineVo.getGroupNo())) {
                resultMap.put("code", -1);
                resultMap.put("message", "药房编码不能为空");
            }
            if (mzRefundMedicineVo.getRealNo() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "流水号不能为空");
            }
            if (mzRefundMedicineVo.getRealNo() == null) {
                resultMap.put("code", -1);
                resultMap.put("message", "流水号不能为空");
            }
            mzRefundMedicineVo.setConfirmFlag(3);
            mzRefundMedicineVo.setConfirmTime(date);
            mzRefundMedicineVo.setConfirmId(userIdCode);
            flag++;
            if (flag == 1) {
                mzPharmacyMapper.updateFytjConfirmFlag(mzRefundMedicineVo);
            }
            mzPharmacyMapper.updateChargeDetailConfirmFlag(mzRefundMedicineVo);
            mzPharmacyMapper.updateBaseYf(mzRefundMedicineVo);
        }
        resultMap.put("code", 0);
        resultMap.put("message", "退药处理成功");
        return resultMap;
    }

    @Override
    public List<ChargeDetailInfoVo> getFyclWfyPrescriptionPage(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectFyclWfyPrescriptionPage(chargeFeeParamsVo);
    }

    @Override
    public int getFyclWfyPrescriptionCount(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectFyclWfyPrescriptionCount(chargeFeeParamsVo);
    }

    @Override
    public int selectMzReceiptSerialCount(ChargeDetailInfoVo chargeDetailInfoVo) {
        return mzPharmacyMapper.selectMzReceiptSerialCount(chargeDetailInfoVo);
    }

    @Override
    public List<ChargeDetailInfoVo> getFyclYfyPrescriptionPage(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectFyclYfyPrescriptionPage(chargeFeeParamsVo);
    }

    @Override
    public int getFyclYfyPrescriptionCount(ChargeFeeParamsVo chargeFeeParamsVo) {
        return mzPharmacyMapper.selectFyclYfyPrescriptionCount(chargeFeeParamsVo);
    }

    @Override
    public List<MzSendMedicineVo> getFyclPrescriptionDetail(MzChargeDetail mzChargeDetail) {
        return mzPharmacyMapper.selectFyclPrescriptionDetail(mzChargeDetail);
    }

    @Override
    public String getYpUnitName(String code) {
        return mzPharmacyMapper.selectYpUnitName(code);
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public Map<String, Object> sendMedicineProcessing(MzChargeDetail mzChargeDetail, User user) throws MzException {
        Map<String, Object> resultMap = new HashMap<>();
        Date date = new Date();
        List<MzSendMedicineVo> cfxxList = mzPharmacyMapper.selectFyclPrescriptionDetail(mzChargeDetail);
        List<YpMzFytj> ypMzFytjs = new ArrayList();
        Employee employee = employeeMapper.selectByUserCode(cfxxList.get(0).getDoctorCode());
        for (MzSendMedicineVo mzSendMedicineVo : cfxxList) {
            if (Double.parseDouble(mzSendMedicineVo.getQuantity()) > 0) {
                YpMzFytj ypMzFytj = new YpMzFytj();
                ypMzFytj.setPatientId(mzSendMedicineVo.getPatientId());
                ypMzFytj.setTimes(mzSendMedicineVo.getTimes());
                ypMzFytj.setReceiptNo(mzSendMedicineVo.getReceiptNo());
                ypMzFytj.setOrderNo(mzSendMedicineVo.getOrderNo());
                ypMzFytj.setQuantity(Double.parseDouble(mzSendMedicineVo.getQuantity()));
                ypMzFytj.setUnitPrice(mzSendMedicineVo.getUnitPrice());
                ypMzFytj.setChargeItemCode(mzSendMedicineVo.getChargeItemCode());
                ypMzFytj.setSerial(mzSendMedicineVo.getSerial());
                ypMzFytj.setGroupNo(mzSendMedicineVo.getGroupNo());
                ypMzFytj.setItemNo(mzSendMedicineVo.getItemNo());
                ypMzFytj.setSerialNo(mzSendMedicineVo.getSerialNo());
                ypMzFytj.setDoctorId(mzSendMedicineVo.getDoctorCode());
                ypMzFytj.setWinNo(mzChargeDetail.getWindowsNoYf());
                ypMzFytj.setDoctorName(employee.getEmployeeName());
                ypMzFytjs.add(ypMzFytj);
            }
        }
        for (YpMzFytj ypMzFytj : ypMzFytjs) {
            ypMzFytj.setConfirmTime(date);
            ypMzFytj.setInputTime(date);
            ypMzFytj.setConfirmId(user.getUserIdCode());
            ypMzFytj.setConfirmName(user.getUserName());
            if(mzPharmacyMapper.insertFyclFytj(ypMzFytj) < 1){
                throw new MzException("保存发药统计数据为空，发药处理失败");
            }
            if(mzPharmacyMapper.updateFyclChargeDetailConfirmFlag(ypMzFytj) < 1){
                throw new MzException("修改发药状态数据为空，发药处理失败");
            }
            MzRefundMedicineVo mzRefundMedicineVo = new MzRefundMedicineVo();
            mzRefundMedicineVo.setChargeCode(ypMzFytj.getChargeItemCode());
            mzRefundMedicineVo.setSerial(ypMzFytj.getSerial());
            mzRefundMedicineVo.setGroupNo(ypMzFytj.getGroupNo());
            mzRefundMedicineVo.setDecAmount(-ypMzFytj.getQuantity());
            mzRefundMedicineVo.setUnitPrice(ypMzFytj.getUnitPrice());
            if(mzPharmacyMapper.updateBaseYf(mzRefundMedicineVo) < 1){
                throw new MzException("更新药房库存数据为空，发药处理失败");
            }
        }
        resultMap.put("code", 0);
        resultMap.put("message", "发药处理成功");
        return resultMap;
    }

    @Override
    public int dispensingMedicineProcessing(MzChargeDetail mzChargeDetail) {
        mzChargeDetail.setConfirmFlag(5);
        return mzPharmacyMapper.updateDispensingChargeDetailConfirmFlag(mzChargeDetail);
    }

    @Override
    public List<RadSendRecord> getRadSendRecordPage(RadSendRecord radSendRecord) {
        return mzPharmacyMapper.selectRadSendRecordPage(radSendRecord);
    }

    @Override
    public Integer getRadSendRecordCount(RadSendRecord radSendRecord) {
        return mzPharmacyMapper.selectRadSendRecordCount(radSendRecord);
    }

    @Override
    public Date getLastRadSendDate(Date date) {
        return mzPharmacyMapper.selectLastRadSendDate(date);
    }

    @Override
    public List<Map<String, Object>> getRadSendStat(String confirmTime) {
        List<Map<String, Object>> list = new ArrayList<>();
        if (confirmTime != "") {
            list = mzPharmacyMapper.selectRadSendStatByConfirmTime(confirmTime);
        } else {
            Date date = mzPharmacyMapper.selectLastRadSendDate(DateUtil.pase(new Date(), "yyyy-MM-dd HH:mm:ss"));
            list = mzPharmacyMapper.selectRadSendStat(DateUtil.fomart(date, "yyyy-MM-dd"),
                    DateUtil.fomart(DateUtil.getPrevDayLastSecond(new Date()), "yyyy-MM-dd HH:mm:ss"));
        }
        for (int i = 0; i < list.size(); i++) {
            Map map = list.get(i);
            String manuName = ypZdManufactoryMapper.selectYpZdManufactoryByCode((String)map.get("manu_code"));
            map.put("manuName", manuName);
            YpBaseYf ypBaseYf = ypBaseYfMapper.selectYpBaseYf((String) map.get("code"), (String) map.get("serial"), "71");
            map.put("location", ypBaseYf.getLocation());
            map.put("stockAmount", ypBaseYf.getStockAmount());
        }
        return list;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public int sendMedicineProcessingRad(User user) {
        Date date = mzPharmacyMapper.selectLastRadSendDate(DateUtil.pase(new Date(), "yyyy-MM-dd HH:mm:ss"));
        String startDateStr = DateUtil.fomart(date, "yyyy-MM-dd");
        String endDateStr = DateUtil.fomart(DateUtil.getPrevDayLastSecond(new Date()), "yyyy-MM-dd HH:mm:ss");
        List<MzChargeDetail> mzChargeDetails = mzPharmacyMapper.selectRadSendPrescription(startDateStr, endDateStr);
        int number = 0;
        Date newDate = new Date();
        for (MzChargeDetail mzChargeDetail : mzChargeDetails) {
            mzChargeDetail.setConfirmFlag(1);
            mzChargeDetail.setConfirmId(user.getUserIdCode());
            mzChargeDetail.setConfirmTime(newDate);
            number += mzPharmacyMapper.updateMzChargeDetailDispensing(mzChargeDetail);
            //更新药房库存
            MzRefundMedicineVo mzRefundMedicineVo = new MzRefundMedicineVo();
            mzRefundMedicineVo.setChargeCode(mzChargeDetail.getChargeItemCode());
            mzRefundMedicineVo.setSerial(mzChargeDetail.getSerial());
            mzRefundMedicineVo.setGroupNo("71");
            mzRefundMedicineVo.setDecAmount(-mzChargeDetail.getQuantity());
            mzRefundMedicineVo.setUnitPrice(mzChargeDetail.getUnitPrice());
            mzPharmacyMapper.updateBaseYf(mzRefundMedicineVo);
        }
        return number;
    }

    @Override
    public int isRadSend(String code) {
        return mzPharmacyMapper.selectIsRadSend( code);
    }
}
