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

import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.Utils.MapUtil;
import cn.hnthyy.thmz.entity.his.YpZdDict;
import cn.hnthyy.thmz.entity.his.mz.Employee;
import cn.hnthyy.thmz.entity.his.zd.ZdChargeItem;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.enums.ZyChargeStatusEnum;
import cn.hnthyy.thmz.mapper.his.yz.*;
import cn.hnthyy.thmz.mapper.his.zy.*;
import cn.hnthyy.thmz.service.his.YpZdDictService;
import cn.hnthyy.thmz.service.his.mz.EmployeeService;
import cn.hnthyy.thmz.service.his.zd.ZdChargeItemService;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
import cn.hnthyy.thmz.service.his.zy.NewZyjsService;
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.text.DecimalFormat;
import java.util.*;

@Service
public class NewZyjsServiceImpl implements NewZyjsService {
    @SuppressWarnings("all")
    @Autowired
    private YzYpZyOrderMapper yzYpZyOrderMapper;
    @SuppressWarnings("all")
    @Autowired
    private YzZyPatientFeeMapper yzZyPatientFeeMapper;
    @SuppressWarnings("all")
    @Autowired
    private YpZyPatientMapper ypZyPatientMapper;
    @SuppressWarnings("all")
    @Autowired
    private ZyDetailChargeMapper zyDetailChargeMapper;
    @SuppressWarnings("all")
    @Autowired
    private YzActOrderMapper yzActOrderMapper;
    @SuppressWarnings("all")
    @Autowired
    private YzEraseOrderMapper yzEraseOrderMapper;
    @SuppressWarnings("all")
    @Autowired
    private YzInactOrderMapper yzInactOrderMapper;
    @SuppressWarnings("all")
    @Autowired
    private ZyLedgerFileMapper zyLedgerFileMapper;
    @SuppressWarnings("all")
    @Autowired
    private ZyReceiptMapper zyReceiptMapper;
    @SuppressWarnings("all")
    @Autowired
    private ZyLedgerFileYbMapper zyLedgerFileYbMapper;
    @SuppressWarnings("all")
    @Autowired
    private ZyOweFileMapper zyOweFileMapper;

    @Autowired
    private ZdUnitCodeService zdUnitCodeService;
    @Autowired
    private ZdChargeItemService zdChargeItemService;
    @Autowired
    private EmployeeService employeeService;
    @Autowired
    private YpZdDictService ypZdDictService;

    @Override
    public List<Map<String, Object>> getActOrders(String inpatientNo, Integer admissTimes) {
        String infantFlag = (inpatientNo.indexOf("$") > 0 ? YesNoEnum.YES.code : YesNoEnum.NO.code).toString();
        List showList = Arrays.asList(ZyChargeStatusEnum.DEPARTMENT_CONFIRMED.code, ZyChargeStatusEnum.DEPARTMENT_ENTRY.code, ZyChargeStatusEnum.MEDICAL_TECHNIQUE_NOT_CONFIRMED.code);
        List<Map<String, Object>> zyDetailCharges = zyDetailChargeMapper.selectZyDetailCharges(inpatientNo, admissTimes, infantFlag, showList);
        List<Map<String, Object>> yzYpZyOrders = yzYpZyOrderMapper.selectZyDetailChargesFromYzYpZyOrder(inpatientNo, admissTimes, infantFlag);
        addZyDetailCharge(showList, zyDetailCharges, yzYpZyOrders);
        List<Map<String, Object>> ypZyPatients = ypZyPatientMapper.selectZyDetailChargesFromYpZyPatient(inpatientNo, admissTimes, infantFlag);
        addZyDetailCharge(showList, zyDetailCharges, ypZyPatients);
        List<Map<String, Object>> yzZyPatientFees = yzZyPatientFeeMapper.selectZyDetailChargesFromYzZyPatientFee(inpatientNo, admissTimes, infantFlag);
        addZyDetailCharge(showList, zyDetailCharges, yzZyPatientFees);
        //按照异常状态排序升序
        zyDetailCharges.sort((o1, o2) -> ((String) o1.get("chargeStatus")).compareTo((String) o2.get("chargeStatus")));
//        Comparator<Map<String, Object>> ageComparator = (o1, o2)->((Integer)o1.get("charge_status")).compareTo((Integer) o2.get("charge_status"));
//        zyDetailCharges.sort(ageComparator);       //按上面配置的顺序取值
//        zyDetailCharges.sort(ageComparator.reversed());    //按上面配置的顺序反向取值


        List<Map<String, Object>> zyActOrderss = yzActOrderMapper.selectZyActOrdersFromYzActOrder(inpatientNo, admissTimes);
        List<Map<String, Object>> yzEraseOrders = yzEraseOrderMapper.selectZyActOrdersFromYzEraseOrder(inpatientNo, admissTimes);
        if (yzEraseOrders != null && yzEraseOrders.size() > 0) {
            zyActOrderss.addAll(yzEraseOrders);
        }
        List<Map<String, Object>> yzInactOrders = yzInactOrderMapper.selectZyActOrdersFromYzInActOrder(inpatientNo, admissTimes);
        if (yzInactOrders != null && yzInactOrders.size() > 0) {
            zyActOrderss.addAll(yzInactOrders);
        }
        Map<String, Object> zylrfy = new HashMap<>();
        zylrfy.put("actOrderNo", 0);
        zylrfy.put("inpatientNo", inpatientNo);
        zylrfy.put("admissTimes", admissTimes);
        zylrfy.put("orderCode", "000000");
        zylrfy.put("orderName", "住院处录入费用");
        zylrfy.put("groupNo", "00");
        zyActOrderss.add(zylrfy);

        Map<String, Object> ssslrfy = new HashMap<>();
        ssslrfy.put("actOrderNo", 3);
        ssslrfy.put("inpatientNo", inpatientNo);
        ssslrfy.put("admissTimes", admissTimes);
        ssslrfy.put("orderCode", "000000");
        ssslrfy.put("orderName", "手术室录入费用");
        ssslrfy.put("groupNo", "00");
        zyActOrderss.add(ssslrfy);

        Map<String, Object> jzfyzl = new HashMap<>();
        jzfyzl.put("actOrderNo", 6);
        jzfyzl.put("inpatientNo", inpatientNo);
        jzfyzl.put("admissTimes", admissTimes);
        jzfyzl.put("orderCode", "000000");
        jzfyzl.put("orderName", "急诊费用转录");
        jzfyzl.put("groupNo", "00");
        zyActOrderss.add(jzfyzl);
        //医嘱map
        Map<String, Map<String, Object>> actOrderMap = new HashMap<>();
        for (Map<String, Object> map : zyActOrderss) {
            Object actOrderNoObj = map.get("actOrderNo");
            String key = null;
            if (actOrderNoObj instanceof Double) {
                Double actOrderNo = Math.abs((Double) actOrderNoObj);
                DecimalFormat df = new DecimalFormat("0");// 最多保留几位小数，就用几个#，最少位就用0来确定
                key = df.format(actOrderNo);
            } else if (actOrderNoObj instanceof Integer) {
                Integer actOrderNo = Math.abs((Integer) actOrderNoObj);
                key = actOrderNo.toString();
            }
            if (actOrderMap.get(key) == null) {
                actOrderMap.put(key, map);
            }
        }
        List<Map<String, Object>> resultMap = new ArrayList<>();
        if (zyDetailCharges != null && zyDetailCharges.size() > 0) {
            Map<Double, Map<String, Object>> orderNoMap = new HashMap<>();
            //医生缓存
            Map<String,Employee> doctorNameMap = new HashMap<>();
            //项目字典缓存
            Map<String,ZdChargeItem> zdChargeItemMap = new HashMap<>();
            //药品字典缓存
            Map<String,YpZdDict> ypZdDictMap = new HashMap<>();
            for (Map<String, Object> map : zyDetailCharges) {
                Double actOrderNo = Math.abs((Double) map.get("orderNo"));
                DecimalFormat df = new DecimalFormat("0");// 最多保留几位小数，就用几个#，最少位就用0来确定
                String key = df.format(actOrderNo);
                map.put("orderNo", key);
                Double pageNo = (Double) map.get("pageNo");
                if (pageNo == null) {
                    map.put("pageNo", "0");
                } else {
                    map.put("pageNo", df.format(Math.abs(pageNo)));
                }
                map.put("chargeDate", DateUtil.fomart((Date) map.get("chargeDate"), "yyyy-MM-dd HH:mm:ss"));
                Map<String, Object> temp = orderNoMap.get(actOrderNo);
                Map<String, Object> actOrder = actOrderMap.get(key);
                List<Map<String, Object>> itemList = null;
                if (temp == null) {
                    temp = new HashMap<>();
                    MapUtil.mapCopy(map, temp);
                    //将第一个子医嘱复制为父医嘱
                    orderNoMap.put(actOrderNo, temp);
                    resultMap.add(temp);
                    itemList = new ArrayList<>();
                    //设置子医嘱列表
                    temp.put("list", itemList);
                    if (actOrder != null) {
                        temp.put("startTime", DateUtil.fomart((Date) actOrder.get("startTime"), "yyyy-MM-dd HH:mm:ss"));
                        temp.put("endTime", DateUtil.fomart((Date) actOrder.get("endTime"), "yyyy-MM-dd HH:mm:ss") );
                        String enterOper=(String) actOrder.get("enterOper");
                        doctorNameMap.get(enterOper);
                        Employee employee=doctorNameMap.get(enterOper);
                        if(employee ==null){
                            employee= employeeService.queryByUserCode(enterOper);
                            doctorNameMap.put(enterOper,employee);
                        }
                        temp.put("enterOper", employee.getEmployeeName());
                        //设置医生的姓名
                        String physician=(String) actOrder.get("physician");
                        employee=doctorNameMap.get(physician);
                        if(employee==null){
                            employee= employeeService.queryByUserCode(physician);
                            doctorNameMap.put(enterOper,employee);
                        }
                        temp.put("physician", employee.getEmployeeName());
                        temp.put("orderName", actOrder.get("orderName"));
                        temp.put("wardName",zdUnitCodeService.queryDeptNameByIdInCache((String) temp.get("wardCode")));
                        temp.put("frequCode",actOrder.get("frequCode"));
                        temp.put("cxFlag",actOrder.get("cxFlag"));
                    }
                } else {
                    itemList = (List<Map<String, Object>>) temp.get("list");
                }
                String chargeCode=(String) map.get("chargeCode");
                YpZdDict ypZdDict=null;
                if(chargeCode.indexOf("BILL")>0){
                    //此时确定是药品
                    String chargeCodeMx=(String) map.get("chargeCodeMx");
                    String serial=(String) map.get("serial");
                    String ypKey=chargeCodeMx+"_"+serial;
                    ypZdDict= ypZdDictMap.get(ypKey);
                    if(ypZdDict==null){
                        ypZdDict=ypZdDictService.queryYpZdDictByCodeAndSerial(chargeCodeMx,serial);
                        ypZdDictMap.put(ypKey,ypZdDict);
                    }
                }else {
                    ypZdDict= ypZdDictMap.get(chargeCode);
                    if(ypZdDict==null){
                       List<YpZdDict> ypZdDicts=ypZdDictService.queryYpZdDictByCode(chargeCode);
                       if(ypZdDicts!=null && ypZdDicts.size()>0){
                           ypZdDict=ypZdDicts.get(0);
                           ypZdDictMap.put(chargeCode,ypZdDict);
                       }
                    }
                }
                if(ypZdDict!=null){
                    //此时是药品
                    map.put("drugSpecification",ypZdDict.getSpecification());
                    map.put("chargeName",ypZdDict.getName());
                }else {
                    //此时是项目
                    ZdChargeItem zdChargeItem=zdChargeItemMap.get(chargeCode);
                    if(zdChargeItem==null){
                        zdChargeItem=zdChargeItemService.queryZdChargeItemByCode(chargeCode);
                        if(zdChargeItem!=null){
                            zdChargeItemMap.put(chargeCode,zdChargeItem);
                            map.put("chargeName",zdChargeItem.getName());
                        }else {
                            //此时是将医嘱名称填入项目名称
                            map.put("chargeName",actOrder.get("orderName"));
                        }
                    }
                }
                itemList.add(map);
            }
        }
        return resultMap;
    }

    private void addZyDetailCharge(List showList, List<Map<String, Object>> zyDetailCharges, List<Map<String, Object>> yzYpZyOrders) {
        if (yzYpZyOrders != null && yzYpZyOrders.size() > 0) {
            for (Map<String, Object> map : yzYpZyOrders) {
                String chargeStatus = (String) map.get("chargeStatus");
                if (showList.contains(chargeStatus)) {
                    zyDetailCharges.add(map);
                }
            }
        }
    }

    @Override
    public Map<String, Object> verification(String staffId, String inpatientNo, Integer admissTimes, Integer dismissFlag, String zjdzDatetime) {
        return null;
    }

    @Override
    public Map<String, Object> execute(String staffId, String inpatientNo, Integer admissTimes, Integer dismissFlag, String zjdzDatetime) {
        return null;
    }

    @Override
    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    public int cancelTheSettlement(String inpatientNo, Integer admissTimes) {
       Integer maxLedgerSn= zyLedgerFileMapper.selectMaxLedgerSn(inpatientNo,admissTimes);
        zyDetailChargeMapper.updateZyDetailChargeForCanCel(inpatientNo,admissTimes,maxLedgerSn);
        zyReceiptMapper.deleteZyReceipt(inpatientNo,admissTimes,maxLedgerSn);
        zyLedgerFileYbMapper.deleteZyLedgerFileYb(inpatientNo,admissTimes,maxLedgerSn);
        zyOweFileMapper.deleteZyOweFile(inpatientNo,admissTimes,maxLedgerSn);
        return zyLedgerFileMapper.updateZyLedgerFileForCanCel(inpatientNo,admissTimes,maxLedgerSn);
    }
}
