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

import com.docus.core.util.Func;
import com.docus.infrastructure.redis.service.IdService;
import com.docus.server.archive.constans.SyncConstant;
import com.docus.server.archive.converter.ZqDyRyPatientInfoConverter;
import com.docus.server.archive.entity.TBasic;
import com.docus.server.archive.mapper.TBasicMapper;
import com.docus.server.archive.service.PatientInfoSyncService;
import com.docus.server.zqdyry.entity.ZqDyRyPatientInfoView;
import com.docus.server.zqdyry.mapper.ZqDyRyPatientInfoViewMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author YongBin Wen
 * @date 2024/3/27 16:25
 */
@Service("ZqDyRy" + SyncConstant.PATIENT_INFO_SYNC_SERVICE_SUFFIX)
@Slf4j
public class ZqDyRyPatientInfoSyncServiceImpl implements PatientInfoSyncService {
    @Resource
    private TBasicMapper tBasicMapper;
    @Resource
    private ZqDyRyPatientInfoViewMapper zqDyRyPatientInfoViewMapper;
    @Resource
    private IdService idService;

    @Override
    public void syncByDisDateRange(LocalDate start, LocalDate end) {
        log.error("肇庆第一人民医院未开发按照出院时间同步患者基础数据！");
    }

    @Override
    public void syncByModifyTimeRange(LocalDateTime start, LocalDateTime end) {
        String startDateTime = Func.formatDateTime(start);
        String endDateTime = Func.formatDateTime(end);
        int size = 1000;
        int pageNumber = 1;
        while (true) {
            int startRow = ((pageNumber - 1) * size) + 1;
            int endRow = pageNumber * size;
            List<ZqDyRyPatientInfoView> patientInfoViews = zqDyRyPatientInfoViewMapper.pageByModifyTime(startDateTime, endDateTime, startRow, endRow);
            if (Func.isNotEmpty(patientInfoViews)) {
                List<TBasic> basicList = patientInfoViews.stream()
                        .map(ZqDyRyPatientInfoConverter::convertPatientInfo)
                        .collect(Collectors.toList());
                saveOrUpdate(basicList);
            }
            if (Func.isEmpty(patientInfoViews) || patientInfoViews.size() < size) {
                break;
            }
            pageNumber++;
        }
    }

    @Override
    public void syncByModifyTimeAndCyrq(String cyrqStart, String startTime) {
        log.error("肇庆第一人民医院未开发按照出院时间和修改时间同步患者基础数据！");
    }

    /**
     * 根据修改的患者基础信息，根据JZH查询是否存在，并进行相应数据的修改和新增。注：肇庆之前的jzh模式为 住院号@住院次数 组成，需要用两种方式查询
     *
     * @param iuBasicList 修改的患者基础信息
     */
    private void saveOrUpdate(List<TBasic> iuBasicList) {
        Date nowDate = new Date();
        List<String> iuJzhList1 = iuBasicList.stream()
                .map(TBasic::getJzh)
                .collect(Collectors.toList());
        List<String> iuJzhList2 = iuBasicList.stream()
                .map(e -> e.getInpatientNo().trim() + "@" + e.getAdmissTimes())
                .collect(Collectors.toList());
        List<String> iuJzhList = new ArrayList<>();
        iuJzhList.addAll(iuJzhList1);
        iuJzhList.addAll(iuJzhList2);
        List<TBasic> existsBasicList = tBasicMapper.getByJzh(iuJzhList);
        Map<String, TBasic> existsJzhBasicMap = existsBasicList.stream().collect(Collectors.toMap(TBasic::getJzh, Function.identity()));

        List<TBasic> insertBasicList = new ArrayList<>();
        List<TBasic> updateBasicList = new ArrayList<>();
        for (TBasic iuBasic : iuBasicList) {
            String maybeJzh = iuBasic.getInpatientNo().trim() + "@" + iuBasic.getAdmissTimes();
            if (existsJzhBasicMap.containsKey(iuBasic.getJzh()) || existsJzhBasicMap.containsKey(maybeJzh)) {
                TBasic basic1 = existsJzhBasicMap.get(iuBasic.getJzh());
                TBasic basic2 = existsJzhBasicMap.get(maybeJzh);
                TBasic tBasic = Objects.isNull(basic1) ? basic2 : basic1;
                tBasic.setName(iuBasic.getName());
                tBasic.setInpatientNo(iuBasic.getInpatientNo());
                tBasic.setAdmissTimes(iuBasic.getAdmissTimes());
                tBasic.setSex(iuBasic.getSex());
                tBasic.setSexName(iuBasic.getSexName());
                tBasic.setNameSpell(iuBasic.getNameSpell());
                tBasic.setJzh(iuBasic.getJzh());
                tBasic.setAdmissDate(iuBasic.getAdmissDate());
                tBasic.setAdmissDept(iuBasic.getAdmissDept());
                tBasic.setAdmissDeptName(iuBasic.getAdmissDeptName());
                tBasic.setBedNo(iuBasic.getBedNo());
                tBasic.setAttending(iuBasic.getAttending());
                tBasic.setAttendingName(iuBasic.getAttendingName());
                tBasic.setAge(iuBasic.getAge());
                tBasic.setAgeMonth(iuBasic.getAgeMonth());
                tBasic.setAgeDay(iuBasic.getAgeDay());
                tBasic.setIdCard(iuBasic.getIdCard());
                tBasic.setTelphone(iuBasic.getTelphone());
                tBasic.setDisDate(iuBasic.getDisDate());
                tBasic.setDisDept(iuBasic.getDisDept());
                tBasic.setDisDeptName(iuBasic.getDisDeptName());
                tBasic.setIsDead(iuBasic.getIsDead());
                tBasic.setTotalCost(iuBasic.getTotalCost());
                tBasic.setFileSource(iuBasic.getFileSource());
                tBasic.setUpdateTime(nowDate);
                updateBasicList.add(tBasic);
                continue;
            }
            iuBasic.setPatientId(String.valueOf(idService.getDateSeq()));
            iuBasic.setCreateTime(nowDate);
            iuBasic.setUpdateTime(nowDate);
            iuBasic.setIsArchive(0);
            iuBasic.setIsOther(0);
            if (iuBasic.getInpatientNo().toLowerCase().contains("b")) {
                iuBasic.setIsOther(1);
            }
            insertBasicList.add(iuBasic);
        }

        if (Func.isNotEmpty(insertBasicList)) {
            tBasicMapper.insertBatch(insertBasicList);
        }
        if (Func.isNotEmpty(updateBasicList)) {
            tBasicMapper.updateBatch(updateBasicList);
        }

    }
}
