package cn.iocoder.yudao.module.system.service.nursing;

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.mybatis.core.query.LambdaQueryWrapperX;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.context.TenantContextHolder;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.CheckInWaitNurseLevelSimpleRespVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.ItemPageReqVO;
import cn.iocoder.yudao.module.system.controller.admin.biz.vo.excel.NurseItemImportExcel;
import cn.iocoder.yudao.module.system.dal.dataobject.biz.*;
import cn.iocoder.yudao.module.system.dal.dataobject.tenant.TenantDO;
import cn.iocoder.yudao.module.system.dal.mysql.biz.*;
import cn.iocoder.yudao.module.system.dal.mysql.tenant.TenantMapper;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
public class NurseLevelServiceImpl implements NurseLevelService {

    @Resource
    private ElderlyInfoMapper elderlyInfoMapper;

    @Resource
    private NurseLevelMapper nurseLevelMapper;

    @Resource
    private NurseItemMapper nurseItemMapper;

    @Resource
    private NurseLevelConfigMapper nurseLevelConfigMapper;

    @Resource
    private NursingCategoryMapper nursingCategoryMapper;

    @Resource
    private NursingCategoryService nursingCategoryService;
    @Resource
    private TenantMapper tenantMapper;

    @Override
    public void addNurseLevel(NurseLevelDO nurseLevel) {
        nurseLevel.setCreateTime(new Date());
        nurseLevelMapper.insert(nurseLevel);
        List<NurseLevelConfigDO> configs = nurseLevel.getConfigs();
        if (CollectionUtil.isNotEmpty(configs)) {
            for (NurseLevelConfigDO config : configs) {
                config.setNurseLevelId(nurseLevel.getId());
                nurseLevelConfigMapper.insert(config);
            }
        }

    }

    @Override
    public void editNurseLevel(NurseLevelDO nurseLevel) {
        nurseLevelMapper.updateById(nurseLevel);
        //先删除在重新生成配置
        nurseLevelConfigMapper.delete(new LambdaQueryWrapperX<NurseLevelConfigDO>().eq(NurseLevelConfigDO::getNurseLevelId, nurseLevel.getId()));
        List<NurseLevelConfigDO> configs = nurseLevel.getConfigs();
        for (NurseLevelConfigDO config : configs) {
            config.setNurseLevelId(nurseLevel.getId());
            nurseLevelConfigMapper.insert(config);
        }
    }

    @Override
    public NurseLevelDO getDetail(Long id) {
        NurseLevelDO nurseLevel = nurseLevelMapper.selectById(id);
        if (nurseLevel != null) {
            List<NurseLevelConfigDO> nurseLevelConfigs = nurseLevelConfigMapper.selectList(new LambdaQueryWrapperX<NurseLevelConfigDO>().eq(NurseLevelConfigDO::getNurseLevelId, nurseLevel.getId()));
            for (NurseLevelConfigDO nurseLevelConfig : nurseLevelConfigs) {
                NurseItemDO itemDO = nurseItemMapper.selectById(nurseLevelConfig.getNurseItemId());
                nurseLevelConfig.setNurseItemName(itemDO.getItemName());
            }
            nurseLevel.setConfigs(nurseLevelConfigs);
        }
        return nurseLevel;
    }

    @Override
    public void deleteById(Long id) {
        nurseLevelMapper.deleteById(id);
        nurseLevelConfigMapper.delete(new LambdaQueryWrapperX<NurseLevelConfigDO>().eq(NurseLevelConfigDO::getNurseLevelId, id));
    }

    @Override
    public PageResult<NurseLevelDO> findPage(ItemPageReqVO pageReqVO) {
        PageResult<NurseLevelDO> pageResult = nurseLevelMapper.selectPage(pageReqVO);
        for (NurseLevelDO nurseLevelDO : pageResult.getList()) {
            TenantDO tenantDO = tenantMapper.selectById(nurseLevelDO.getTenantId());
            nurseLevelDO.setTenantName(tenantDO == null ? null : tenantDO.getName());
        }
        return pageResult;
    }

    @Override
    public List<NurseLevelConfigDO> getListByElderId(Long elderId, String categoryTypeName) {
        //查询生活护理或者医疗护理下面所有的分类
        NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectOne(new LambdaQueryWrapperX<NursingCategoryDO>()
                .eq(NursingCategoryDO::getCategoryName, categoryTypeName)
                .eq(NursingCategoryDO::getParentId, 0));

        //查询所有分类ID
        List<Long> ids = nursingCategoryService.getIdListByParent(nursingCategoryDO.getId());
        ElderlyInfoDO elderlyInfo = elderlyInfoMapper.selectById(elderId);
        if (elderlyInfo != null) {
            Long nurseLevelId = elderlyInfo.getNurseLevelId();
            List<NurseLevelConfigDO> nurseLevelConfigList = nurseLevelConfigMapper.selectList(new LambdaQueryWrapperX<NurseLevelConfigDO>()
                    .eq(NurseLevelConfigDO::getNurseLevelId, nurseLevelId));


            List<NurseLevelConfigDO> dataList = new ArrayList<>();
            for (NurseLevelConfigDO nurseLevelConfig : nurseLevelConfigList) {
                NurseItemDO itemDO = nurseItemMapper.selectById(nurseLevelConfig.getNurseItemId());
                nurseLevelConfig.setNurseItemName(itemDO.getItemName());
                for (Long id : ids) {
                    if (itemDO.getCategoryId().equals(id)) {
                        dataList.add(nurseLevelConfig);
                    }
                }
            }
            return dataList;
        }
        return null;
    }

    @Override
    public List<NurseItemDO> findNurseItemListByName(String nurseItemName, String categoryTypeName) {
        //查询生活护理或者医疗护理下面所有的分类
        NursingCategoryDO nursingCategoryDO = nursingCategoryMapper.selectOne(new LambdaQueryWrapperX<NursingCategoryDO>()
                .eq(NursingCategoryDO::getCategoryName, categoryTypeName)
                .eq(NursingCategoryDO::getParentId, 0));
        if(nursingCategoryDO == null){
            return new ArrayList<>();
        }
        //查询所有分类ID
        List<Long> ids = nursingCategoryService.getIdListByParent(nursingCategoryDO.getId());
        List<NurseItemDO> nurseItems = nurseItemMapper.selectList(new LambdaQueryWrapperX<NurseItemDO>()
                .likeIfPresent(NurseItemDO::getItemName, nurseItemName)
                .in(NurseItemDO::getCategoryId, ids));

        for (NurseItemDO nurseItem : nurseItems) {
            NursingCategoryDO nursingCategory = nursingCategoryMapper.selectById(nurseItem.getCategoryId());
            nurseItem.setCategoryName(nursingCategory == null ? null : nursingCategory.getCategoryName());
        }
        return nurseItems;
    }

    @Override
    public Map<String, Object> importNurseItem(List<NurseItemImportExcel> dataList) {
        List<NurseItemImportExcel> errorList = new ArrayList<>();
        Map<String, Object> map = new HashMap<>();
        int i = 0;
        for (NurseItemImportExcel nurseItemImportExcel : dataList) {
            Optional<NursingCategoryDO> optional = nursingCategoryMapper.selectList(new LambdaQueryWrapperX<NursingCategoryDO>()
                    .eq(NursingCategoryDO::getCategoryName, nurseItemImportExcel.getCategoryName())).stream().findFirst();

            if (!optional.isPresent()) {
                nurseItemImportExcel.setErrorMsg(nurseItemImportExcel.getCategoryName() + "分类不存在");
                errorList.add(nurseItemImportExcel);
                continue;
            }
            NurseItemDO nurseItemDO = new NurseItemDO();
            BeanUtils.copyProperties(nurseItemImportExcel, nurseItemDO);
            nurseItemDO.setStatus(1);
            nurseItemDO.setCategoryId(optional.get().getId());
            nurseItemDO.setTenantId(TenantContextHolder.getTenantId());
            nurseItemMapper.insert(nurseItemDO);
            i++;
        }
        map.put("successCount",i);
        map.put("failCount",errorList.size());
        map.put("errorList",errorList);
        return map;
    }

    @Override
    public List<CheckInWaitNurseLevelSimpleRespVO> getNurseLevelListByTenantId(Long tenantId) {
        List<NurseLevelDO> nurseLevels = nurseLevelMapper.selectList(new LambdaQueryWrapperX<NurseLevelDO>()
                .eq(NurseLevelDO::getTenantId, tenantId)
                .orderByAsc(NurseLevelDO::getSort)
                .orderByDesc(NurseLevelDO::getCreateTime));
        return nurseLevels.stream().map(level -> {
            CheckInWaitNurseLevelSimpleRespVO respVO = new CheckInWaitNurseLevelSimpleRespVO();
            respVO.setNurseLevelId(level.getId());
            respVO.setNurseLevelName(level.getNurseLevelName());
            return respVO;
        }).collect(java.util.stream.Collectors.toList());
    }
}
