package com.kcim.dao.repository;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.util.PageUtils;
import com.kcim.common.util.UserContext;
import com.kcim.dao.mapper.ImportPatientItemMapper;
import com.kcim.dao.model.ImportPatientItem;
import com.kcim.dao.model.dto.PatientItemDepartmentGroupVo;
import com.kcim.dao.model.dto.PatientItemVo;
import com.kcim.vo.PatientInfoVo;
import com.kcim.vo.SessionUserVO;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @program: CostAccount
 * @description: 患者收费项目导入数据库交互
 * @author: Wang.YS
 * @create: 2023-10-19 14:20
 **/
@Repository
public class ImportPatientItemRepository extends ServiceImpl<ImportPatientItemMapper, ImportPatientItem> {
    public Page<ImportPatientItem> getPage(Integer current, Integer pageSize, String computeDate, String itemType, String departmentName, String patientNo, String filter) {
        Page<ImportPatientItem> page = new Page<>(current, pageSize);
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, UserContext.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        if (!StringUtils.isEmpty(itemType)) {
            queryWrapper.like(ImportPatientItem::getItemTypeCode, itemType);
        }
        if (!StringUtils.isEmpty(departmentName)) {
            queryWrapper.like(ImportPatientItem::getOrderDepartmentName, departmentName);
        }
        if (!StringUtils.isEmpty(patientNo)) {
            queryWrapper.eq(ImportPatientItem::getPatientNo, patientNo);
        }
        if (!StringUtils.isEmpty(filter)) {
            queryWrapper.and(q -> q.like(ImportPatientItem::getItemCode, filter).or().like(ImportPatientItem::getItemName, filter));
        }
        return this.page(page, queryWrapper);

    }

    public List<ImportPatientItem> getByComputeDate(String computeDate) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, UserContext.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        return this.list(queryWrapper);
    }

    public List<PatientItemVo> getAllGroupByCompute(String computeDate) {
        return baseMapper.getAllGroupByCompute(computeDate, UserContext.getHospId());
    }

    public List<ImportPatientItem> getByComputeDate(String computeDate, String itemType, String departmentName) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, UserContext.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        if (!StringUtils.isEmpty(itemType)) {
            queryWrapper.like(ImportPatientItem::getItemTypeCode, itemType);
        }
        if (!StringUtils.isEmpty(departmentName)) {
            queryWrapper.like(ImportPatientItem::getOrderDepartmentName, departmentName);
        }
        return this.list(queryWrapper);
    }

    public List<PatientItemVo> getAllGroupByOrder(String computeDate) {
        return baseMapper.getAllGroupByOrder(computeDate, UserContext.getHospId());
    }


    public long getCount(String computeDate, SessionUserVO currentUser) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        return this.count(queryWrapper);
    }

    public void updateCalculateFlag(String computeDate, SessionUserVO currentUser) {
        UpdateWrapper<ImportPatientItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ImportPatientItem::getHospId, currentUser.getHospId())
                .eq(ImportPatientItem::getComputeDate, computeDate)
                .eq(ImportPatientItem::getDelFlag, NumberConstant.ZERO)
                .set(ImportPatientItem::getCalculateFlag, 0);

//        updateWrapper.eq("hosp_id", currentUser.getHospId());
//        updateWrapper.eq("compute_date", computeDate);
        this.update(updateWrapper);

    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<ImportPatientItem> getByNoCalculateComputeDate(String computeDate, SessionUserVO currentUser) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        queryWrapper.eq(ImportPatientItem::getCalculateFlag, NumberConstant.ZERO);
        queryWrapper.last("limit 1000");
        return this.list(queryWrapper);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<ImportPatientItem> getByNoCalculateComputeDateDrugMaterial(String computeDate, SessionUserVO currentUser) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(2);
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        queryWrapper.eq(ImportPatientItem::getCalculateFlag, NumberConstant.ZERO);
        queryWrapper.in(ImportPatientItem::getItemTypeCode, list);
        queryWrapper.last("limit 1000");
        return this.list(queryWrapper);
    }

    public List<PatientItemDepartmentGroupVo> getByNoCalculateComputeDateDrugMaterial(Integer current, Integer pageSize,String computeDate, SessionUserVO currentUser) {
        return baseMapper.getByNoCalculateComputeDateDrugMaterial(new Page<>(current, pageSize), computeDate, currentUser.getHospId());

    }

    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRED)
    public void updateCalculateFlag(List<ImportPatientItem> items) {
        items.forEach(f -> f.setCalculateFlag(NumberConstant.ONE));
        this.updateBatchById(items, 500);


    }

    public long getDrugCount(String computeDate, SessionUserVO currentUser) {
//        List<Integer> list = new ArrayList<>();
//        list.add(1);
//        list.add(2);
//        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
//        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
//        queryWrapper.in(ImportPatientItem::getItemTypeCode, list);
//        return this.count(queryWrapper);
        return this.baseMapper.getDrugCount(computeDate,currentUser.getHospId());
    }

    public long getItemCount(String computeDate, SessionUserVO currentUser) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        queryWrapper.eq(ImportPatientItem::getItemTypeCode, NumberConstant.THREE);
        return this.count(queryWrapper);
    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<ImportPatientItem> getByNoCalculateComputeDateItem(String computeDate, SessionUserVO currentUser) {

        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, currentUser.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        queryWrapper.eq(ImportPatientItem::getCalculateFlag, NumberConstant.ZERO);
        queryWrapper.eq(ImportPatientItem::getItemTypeCode, NumberConstant.THREE);
        queryWrapper.last("limit 1000");
        return this.list(queryWrapper);
    }

    public PageUtils getPatientItemPatientInfo(Integer current, Integer pageSize,String computeDate, String filter) {
        Page<PatientInfoVo> page = new Page<>(current,pageSize);
        List<PatientInfoVo> byPage = this.baseMapper.getPatientItemPatientInfo(page,computeDate, filter, UserContext.getHospId());
        if(!CollectionUtils.isEmpty(byPage)){
            page.setRecords(byPage);
        }
        PageUtils pageUtils = new PageUtils(page);
        pageUtils.setList(byPage);
        return pageUtils;
    }

    public void removePatientItemByFileId(String computeDate, Long fileId) {
        LambdaQueryWrapper<ImportPatientItem> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ImportPatientItem::getHospId, UserContext.getHospId());
        queryWrapper.eq(ImportPatientItem::getComputeDate, computeDate);
        queryWrapper.eq(ImportPatientItem::getFileId, fileId);
        List<ImportPatientItem> list = this.list(queryWrapper);
        if (!CollectionUtils.isEmpty(list)) {
            for (ImportPatientItem patientInfo : list) {
                patientInfo.setDeleteTime(new Date());
                patientInfo.setDeleteUser(String.valueOf(UserContext.getCurrentUser().getId()));
            }
            this.updateBatchById(list);
            List<Integer> collect = list.stream().map(ImportPatientItem::getId).collect(Collectors.toList());
            this.removeBatchByIds(collect);
        }
    }

    public void reducingPatientItemByFileId(String computeDate, Long fileId) {
        this.baseMapper.reducingPatientItemByFileId(computeDate, UserContext.getHospId(), fileId, new Date(), String.valueOf(UserContext.getCurrentUser().getId()));

    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<PatientItemDepartmentGroupVo> getByDepartGroupComputeDateItem(String computeDate, SessionUserVO currentUser) {
        return baseMapper.getByDepartGroupComputeDateItem(computeDate, currentUser.getHospId());

    }

    @Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
    public List<PatientItemDepartmentGroupVo> getByDepartGroupComputeDateItem(Integer current, Integer pageSize, String computeDate, SessionUserVO currentUser) {
        return baseMapper.getByDepartGroupComputeDateItem(new Page<PatientItemDepartmentGroupVo>(current, pageSize), computeDate, currentUser.getHospId());

    }

    public void updateCalculateFlag(List<PatientItemDepartmentGroupVo> items, String computeDate, SessionUserVO currentUser) {
        List<Long> collect = items.stream().map(PatientItemDepartmentGroupVo::getId).collect(Collectors.toList());
        UpdateWrapper<ImportPatientItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ImportPatientItem::getDelFlag, NumberConstant.ZERO)
                .eq(ImportPatientItem::getHospId, currentUser.getHospId())
                .eq(ImportPatientItem::getComputeDate, computeDate)
                .in(ImportPatientItem::getId, collect)
                .set(ImportPatientItem::getCalculateFlag, NumberConstant.ONE);


        this.update(updateWrapper);


    }

    public void updateGroupCalculateFlag(String computeDate, SessionUserVO currentUser) {
        UpdateWrapper<ImportPatientItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ImportPatientItem::getHospId, currentUser.getHospId())
                .eq(ImportPatientItem::getComputeDate, computeDate)
                .eq(ImportPatientItem::getDelFlag, NumberConstant.ZERO)
                .eq(ImportPatientItem::getItemTypeCode, NumberConstant.THREE)
                .set(ImportPatientItem::getCalculateFlag, 0);

//        updateWrapper.eq("hosp_id", currentUser.getHospId());
//        updateWrapper.eq("compute_date", computeDate);
        this.update(updateWrapper);

    }

    public long getItemGroupCount(String computeDate, SessionUserVO currentUser) {
        return baseMapper.getItemGroupCount(computeDate, currentUser.getHospId());

    }

    public List<PatientItemDepartmentGroupVo> getPatientItemGroupList(Integer current, Integer pageSize, String computeDate, SessionUserVO currentUser) {

        return baseMapper.getPatientItemGroupList(new Page<PatientItemDepartmentGroupVo>(current, pageSize), computeDate, currentUser.getHospId());

    }

    public long getPatientItemGroupCount(String computeDate, SessionUserVO currentUser) {
        return baseMapper.getPatientItemGroupCount(computeDate, currentUser.getHospId());

    }

    public void updateFilterCalculateFlag(List<PatientItemDepartmentGroupVo> items, String computeDate, SessionUserVO currentUser) {
        List<String> visitList = items.stream().map(PatientItemDepartmentGroupVo::getVisitNo).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        List<String> itemList = items.stream().map(PatientItemDepartmentGroupVo::getItemCode).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());
        List<String> departList = items.stream().map(PatientItemDepartmentGroupVo::getExecuteDepartmentCode).collect(Collectors.toList()).stream().distinct().collect(Collectors.toList());

        UpdateWrapper<ImportPatientItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ImportPatientItem::getDelFlag, NumberConstant.ZERO)
                .eq(ImportPatientItem::getHospId, currentUser.getHospId())
                .eq(ImportPatientItem::getItemTypeCode, NumberConstant.THREE)
                .eq(ImportPatientItem::getComputeDate, computeDate)
                .eq(ImportPatientItem::getCalculateFlag, NumberConstant.ZERO)
                .and(q -> q
                        .in(ImportPatientItem::getVisitNo, visitList)
                        .in(ImportPatientItem::getItemCode, itemList)
                        .in(ImportPatientItem::getExecuteDepartmentCode, departList))
                .set(ImportPatientItem::getCalculateFlag, NumberConstant.ONE);


        this.update(updateWrapper);
    }

    public List<PatientItemDepartmentGroupVo> getDepartAmountGroup(String computeDate, SessionUserVO currentUser) {

        return this.baseMapper.getDepartAmountGroup(computeDate, currentUser.getHospId());
    }

    public void removeByComputeDate(String computeDate) {
        UpdateWrapper<ImportPatientItem> updateWrapper = new UpdateWrapper<>();
        updateWrapper.lambda().eq(ImportPatientItem::getHospId, UserContext.getHospId())
                .eq(ImportPatientItem::getComputeDate, computeDate)
                .eq(ImportPatientItem::getDelFlag, NumberConstant.ZERO)
                .set(ImportPatientItem::getDelFlag, 1);
        this.update(updateWrapper);
    }
}
