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

import cn.hnthyy.thmz.Utils.DateUtil;
import cn.hnthyy.thmz.common.Constants;
import cn.hnthyy.thmz.entity.his.mz.Employee;
import cn.hnthyy.thmz.entity.his.mz.MzDepositFile;
import cn.hnthyy.thmz.entity.his.mz.MzVisitTable;
import cn.hnthyy.thmz.enums.YesNoEnum;
import cn.hnthyy.thmz.mapper.his.mz.EmployeeMapper;
import cn.hnthyy.thmz.mapper.his.mz.MzDepositFileMapper;
import cn.hnthyy.thmz.mapper.his.mz.MzVisitTableMapper;
import cn.hnthyy.thmz.service.his.mz.MzDepositFileService;
import cn.hnthyy.thmz.service.his.zd.ZdUnitCodeService;
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.*;
import java.util.stream.Collectors;

@Service
public class MzDepositFileServiceImpl implements MzDepositFileService {
    @SuppressWarnings("all")
    @Autowired
    private MzDepositFileMapper mzDepositFileMapper;
    @SuppressWarnings("all")
    @Autowired
    private MzVisitTableMapper mzVisitTableMapper;
    @Autowired
    private ZdUnitCodeService zdUnitCodeService;
    @SuppressWarnings("all")
    @Autowired
    private EmployeeMapper employeeMapper;

    @Override
    public int saveMzDepositFile(MzDepositFile mzDepositFile) {
        return mzDepositFileMapper.insertMzDepositFile(mzDepositFile);
    }


    @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.DEFAULT, timeout = 36000, rollbackFor = Exception.class)
    @Override
    public int batchSaveMzDepositFile(List<MzDepositFile> mzDepositFileList) {
        if (mzDepositFileList.size() == 0) {
            return 0;
        }
        if (mzDepositFileList.size() <= 20) {
            mzDepositFileMapper.batchInsertMzDepositFile(mzDepositFileList);
        } else {
            List<MzDepositFile> tempList = new ArrayList<>();
            for (MzDepositFile md : mzDepositFileList) {
                tempList.add(md);
                if (tempList.size() == 20) {
                    mzDepositFileMapper.batchInsertMzDepositFile(tempList);
                    tempList.clear();
                }
            }
            if (tempList.size() > 0) {
                mzDepositFileMapper.batchInsertMzDepositFile(tempList);
            }
        }
        return mzDepositFileList.size();
    }

    @Override
    public List<MzDepositFile> queryMzDepositFile(MzDepositFile mzDepositFile) {
        String receiptSerialTableName="mz_deposit_file";
        List<MzDepositFile> mzDepositFileList=mzDepositFileMapper.selectMzDepositFileByTimes(mzDepositFile.getPatientId(), mzDepositFile.getTimes(), mzDepositFile.getReceiptNo(),receiptSerialTableName);
        if(mzDepositFileList!=null && mzDepositFileList.size()>0){
            return mzDepositFileList;
        }
        receiptSerialTableName="mz_deposit_file_b";
        return mzDepositFileMapper.selectMzDepositFileByTimes(mzDepositFile.getPatientId(), mzDepositFile.getTimes(), mzDepositFile.getReceiptNo(),receiptSerialTableName);
    }

    @Override
    public MzDepositFile queryMzDepositFileByAgtordnum(String psordnum, String agtordnum, String tableName) {
        if (tableName == null) {
            tableName = "mz_deposit_file";
        }
        return mzDepositFileMapper.selectMzDepositFileByAgtordnum(psordnum, agtordnum, tableName);
    }

    @Override
    public BigDecimal queryAmount(Date beginDate, Date endDate) {
        return mzDepositFileMapper.selectAmount(beginDate, endDate);
    }

    @Override
    public List<Map<String, Object>> countAndAmount(Date beginDate, Date endDate, String payMark) {
        return mzDepositFileMapper.countAndAmount(beginDate, endDate, payMark);
    }

    @Override
    public List<Map<String, Object>> queryMzDepositFileForZZ(MzDepositFile mzDepositFile) {
        mzDepositFile.setPageSize(1000);
        mzDepositFile.setOpId(Constants.BRZZJF_CODE);
        mzDepositFile.setOrderByCase("dcount_date");
        mzDepositFile.setTableName("mz_deposit_file");
        List<MzDepositFile> list = mzDepositFileMapper.selectMzDepositFileWithPage(mzDepositFile);
        List<Map<String, Object>> resultList = new ArrayList<>();
        Map<String, String> employeeMap = null;
        Set<String> set = new HashSet<>();
        employeeMap = getStringStringMap(list, resultList, employeeMap, set, YesNoEnum.NO);
        mzDepositFile.setTableName("mz_deposit_file_b");
        list = mzDepositFileMapper.selectMzDepositFileWithPage(mzDepositFile);
        getStringStringMap(list, resultList, employeeMap, set, YesNoEnum.YES);
        return resultList;
    }

    private Map<String, String> getStringStringMap(List<MzDepositFile> list, List<Map<String, Object>> resultList, Map<String, String> employeeMap, Set<String> set, YesNoEnum hisData) {
        if (list != null && list.size() > 0) {
            if (employeeMap == null) {
                List<Employee> employees = employeeMapper.selectAll();
                if (employees != null) {
                    employeeMap = employees.stream().collect(Collectors.toMap(Employee::getEmployeeCode, Employee::getEmployeeName));
                }
            }
            for (MzDepositFile mf : list) {
                String hisOrdNum = mf.getPatientId() + "_" + mf.getTimes() + "_" + mf.getReceiptNo();
                if (set.contains(hisOrdNum)) {
                    continue;
                }
                Map<String, Object> map = new HashMap<>();
                map.put("chargeDate", DateUtil.fomart(mf.getChargeDate(), "yyyy-MM-dd HH:mm:ss"));
                map.put("amount", mf.getAmount());
                map.put("hisOrdNum", hisOrdNum);
                MzVisitTable mzVisitTable = mzVisitTableMapper.selectByPatientIdAndTimes(mf.getPatientId(), mf.getTimes(),"mz_visit_table");
                if (mzVisitTable == null && YesNoEnum.YES.equals(hisData)) {
                    mzVisitTable = mzVisitTableMapper.selectHisDataByPatientIdAndTimes(mf.getPatientId(), mf.getTimes());
                }
                if (mzVisitTable != null) {
                    map.put("visitDeptName", zdUnitCodeService.queryDeptNameByIdInCache(mzVisitTable.getVisitDeptCode()));
                    String doctorName = employeeMap.get(mzVisitTable.getDoctorCode());
                    map.put("doctorName", doctorName == null ? "" : doctorName);
                }
                set.add(hisOrdNum);
                resultList.add(map);
            }
        }
        return employeeMap;
    }
}
