package com.openhis.web.personalization.appservice.impl;

import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.core.common.core.domain.R;
import com.core.common.exception.ServiceException;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.SecurityUtils;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.BindingType;
import com.openhis.common.enums.Whether;
import com.openhis.common.utils.EnumUtils;
import com.openhis.template.domain.OrdersGroupPackage;
import com.openhis.template.domain.OrdersGroupPackageDetail;
import com.openhis.template.service.IOrdersGroupPackageDetailService;
import com.openhis.template.service.IOrdersGroupPackageService;
import com.openhis.web.doctorstation.appservice.IDoctorStationAdviceAppService;
import com.openhis.web.doctorstation.dto.AdviceBaseDto;
import com.openhis.web.personalization.appservice.IOrdersGroupPackageAppService;
import com.openhis.web.personalization.dto.*;
import com.openhis.web.personalization.mapper.OrdersGroupPackageAppMapper;

/**
 * 组合套餐 实现类
 *
 * @author yangmo
 * @date 2025-04-10
 */
@Service
public class OrdersGroupPackageAppServiceImpl implements IOrdersGroupPackageAppService {

    @Resource
    OrdersGroupPackageAppMapper ordersGroupPackageAppMapper;

    @Resource
    IOrdersGroupPackageService ordersGroupPackageService;

    @Resource
    IOrdersGroupPackageDetailService ordersGroupPackageDetailService;

    @Resource
    IDoctorStationAdviceAppService iDoctorStationAdviceAppService;

    /**
     * 保存组合套餐
     *
     * @param ordersGroupPackageSaveDto 保存组合套餐dto
     * @param packageTypeEnum 类型枚举
     * @return 结果
     */
    @Override
    public R<?> saveGroupPackage(OrdersGroupPackageSaveDto ordersGroupPackageSaveDto, Integer packageTypeEnum) {
        // 组合套餐id
        Long groupPackageId = ordersGroupPackageSaveDto.getGroupPackageId();

        if (BindingType.PERSONAL.getValue().equals(packageTypeEnum)
            && ordersGroupPackageSaveDto.getPractitionerId() == null) {
            throw new ServiceException("个人组套需选择人员");
        } else if (BindingType.ORGANIZATION.getValue().equals(packageTypeEnum)
            && ordersGroupPackageSaveDto.getOrganizationId() == null) {
            throw new ServiceException("科室组套需选择科室");
        }
        // 保存主表
        OrdersGroupPackage ordersGroupPackage = new OrdersGroupPackage();
        ordersGroupPackage.setId(groupPackageId);
        ordersGroupPackage.setName(ordersGroupPackageSaveDto.getName());// 名称
        ordersGroupPackage.setPackageTypeEnum(packageTypeEnum);// 组套包类型
        ordersGroupPackage.setOrganizationId(ordersGroupPackageSaveDto.getOrganizationId()); // 科室id
        ordersGroupPackage.setPractitionerId(ordersGroupPackageSaveDto.getPractitionerId()); // 参与者id
        ordersGroupPackageService.saveOrUpdate(ordersGroupPackage);

        // 编辑场景时,先删除原有的明细再新增
        if (groupPackageId != null) {
            ordersGroupPackageDetailService.remove(new LambdaQueryWrapper<OrdersGroupPackageDetail>()
                .eq(OrdersGroupPackageDetail::getGroupPackageId, groupPackageId));
        }
        // 保存明细表
        List<OrdersGroupPackageDetailSaveDto> detailList = ordersGroupPackageSaveDto.getDetailList();
        OrdersGroupPackageDetail ordersGroupPackageDetail;
        for (OrdersGroupPackageDetailSaveDto ordersGroupPackageDetailSaveDto : detailList) {
            ordersGroupPackageDetail = new OrdersGroupPackageDetail();
            ordersGroupPackageDetail.setGroupPackageId(ordersGroupPackage.getId()); // 组合套餐id
            ordersGroupPackageDetail.setOrderDefinitionId(ordersGroupPackageDetailSaveDto.getOrderDefinitionId()); // 医嘱定义id
            ordersGroupPackageDetail.setOrderDefinitionTable(ordersGroupPackageDetailSaveDto.getOrderDefinitionTable());// 医嘱定义表名
            ordersGroupPackageDetail.setQuantity(ordersGroupPackageDetailSaveDto.getQuantity()); // 数量
            ordersGroupPackageDetail.setUnitCode(ordersGroupPackageDetailSaveDto.getUnitCode()); // 单位
            ordersGroupPackageDetail.setDose(ordersGroupPackageDetailSaveDto.getDose()); // 单次剂量
            ordersGroupPackageDetail.setRateCode(ordersGroupPackageDetailSaveDto.getRateCode()); // 用药频次
            ordersGroupPackageDetail.setDispensePerDuration(ordersGroupPackageDetailSaveDto.getDispensePerDuration()); // 用药天数
            ordersGroupPackageDetail.setMethodCode(ordersGroupPackageDetailSaveDto.getMethodCode()); // 给药途径
            ordersGroupPackageDetail.setDoseQuantity(ordersGroupPackageDetailSaveDto.getDoseQuantity()); // 小单位单次剂量
            ordersGroupPackageDetail.setGroupId(ordersGroupPackageDetailSaveDto.getGroupId()); // 组号
            ordersGroupPackageDetailService.save(ordersGroupPackageDetail);
        }

        return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00002, new Object[] {"组合套餐"}));
    }

    /**
     * 查询组合套餐
     *
     * @param packageTypeEnum 类型枚举
     * @param searchKey 模糊查询关键字
     * @return 组合套餐
     */
    @Override
    public List<OrdersGroupPackageQueryDto> getGroupPackage(Integer packageTypeEnum, String searchKey) {
        List<OrdersGroupPackageQueryDto> groupPackage =
            ordersGroupPackageAppMapper.getGroupPackage(packageTypeEnum, null, null, searchKey);
        for (OrdersGroupPackageQueryDto ordersGroupPackageQueryDto : groupPackage) {
            ordersGroupPackageQueryDto.setPackageTypeEnum_enumText(
                EnumUtils.getInfoByValue(BindingType.class, ordersGroupPackageQueryDto.getPackageTypeEnum()));
        }
        return groupPackage;
    }

    /**
     * 查询组合套餐明细
     *
     * @param groupPackageId 组合套餐id
     * @return 组合套餐明细
     */
    @Override
    public List<OrdersGroupPackageDetailQueryDto> getGroupPackageDetail(Long groupPackageId) {
        return ordersGroupPackageAppMapper.getGroupPackageDetail(List.of(groupPackageId));
    }

    /**
     * 删除组合套餐
     *
     * @param groupPackageId 组合套餐id
     * @return 结果
     */
    @Override
    public R<?> delGroupPackage(Long groupPackageId) {
        // 删除主表
        ordersGroupPackageService.removeById(groupPackageId);
        // 删除明细
        ordersGroupPackageDetailService.remove(new LambdaQueryWrapper<OrdersGroupPackageDetail>()
            .eq(OrdersGroupPackageDetail::getGroupPackageId, groupPackageId));
        return R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[] {"组合套餐"}));
    }

    /**
     * 查询组合套餐,供开立医嘱使用
     *
     * @param organizationId 患者挂号对应的科室id
     * @return 组合套餐
     */
    @Override
    public OrdersGroupPackageUseDto getGroupPackageForOrder(Long organizationId) {
        OrdersGroupPackageUseDto ordersGroupPackageUseDto = new OrdersGroupPackageUseDto();
        // 当前参参与者id
        Long practitionerId = SecurityUtils.getLoginUser().getPractitionerId();
        // 当前登录账号的科室id
        Long orgId = SecurityUtils.getLoginUser().getOrgId();

        // 个人组套
        List<OrdersGroupPackageQueryDto> personalGroupPackage =
            ordersGroupPackageAppMapper.getGroupPackage(BindingType.PERSONAL.getValue(), null, practitionerId, null);
        if (!personalGroupPackage.isEmpty()) {
            List<OrdersGroupPackageDto> personalList = personalGroupPackage.stream().map(queryDto -> {
                OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
                dto.setGroupPackageId(queryDto.getGroupPackageId());
                dto.setName(queryDto.getName());
                return dto;
            }).collect(Collectors.toList());
            List<Long> groupPackageIds =
                personalList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
            // 明细项
            List<OrdersGroupPackageDetailQueryDto> personalGroupPackageDetail =
                ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
            // 明细项赋值
            if (!personalGroupPackageDetail.isEmpty()) {
                // 医嘱定义id集合
                List<Long> orderDefinitionIdParamList = personalGroupPackageDetail.stream()
                    .map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
                // 医嘱下拉详细信息
                List<AdviceBaseDto> personalRecords =
                    iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
                        organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3)).getRecords();
                // 创建AdviceBaseDto的映射，以adviceDefinitionId为key
                Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
                    .toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key，保留第一个
                    ));
                // 遍历personalGroupPackageDetail，进行匹配赋值
                for (OrdersGroupPackageDetailQueryDto detail : personalGroupPackageDetail) {
                    Long orderDefinitionId = detail.getOrderDefinitionId();
                    if (orderDefinitionId != null) {
                        AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
                        if (matchedAdvice != null) {
                            detail.setOrderDetailInfos(matchedAdvice);
                        }
                    }
                }
                // 将明细数据按groupPackageId分组
                Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = personalGroupPackageDetail.stream()
                    .collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
                personalList.forEach(dto -> {
                    List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
                    dto.setDetailList(details != null ? details : Collections.emptyList());
                });
            }
            ordersGroupPackageUseDto.setPersonalList(personalList);
        }
        // 科室组套
        List<OrdersGroupPackageQueryDto> organizationGroupPackage =
            ordersGroupPackageAppMapper.getGroupPackage(BindingType.ORGANIZATION.getValue(), orgId, null, null);
        if (!organizationGroupPackage.isEmpty()) {
            List<OrdersGroupPackageDto> organizationList = organizationGroupPackage.stream().map(queryDto -> {
                OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
                dto.setGroupPackageId(queryDto.getGroupPackageId());
                dto.setName(queryDto.getName());
                return dto;
            }).collect(Collectors.toList());
            List<Long> groupPackageIds =
                organizationList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
            // 明细项
            List<OrdersGroupPackageDetailQueryDto> organizationGroupPackageDetail =
                ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
            // 明细项赋值
            if (!organizationGroupPackageDetail.isEmpty()) {
                // 医嘱定义id集合
                List<Long> orderDefinitionIdParamList = organizationGroupPackageDetail.stream()
                    .map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
                // 医嘱下拉详细信息
                List<AdviceBaseDto> personalRecords =
                    iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
                        organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3)).getRecords();
                // 创建AdviceBaseDto的映射，以adviceDefinitionId为key
                Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
                    .toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key，保留第一个
                    ));
                // 遍历personalGroupPackageDetail，进行匹配赋值
                for (OrdersGroupPackageDetailQueryDto detail : organizationGroupPackageDetail) {
                    Long orderDefinitionId = detail.getOrderDefinitionId();
                    if (orderDefinitionId != null) {
                        AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
                        if (matchedAdvice != null) {
                            detail.setOrderDetailInfos(matchedAdvice);
                        }
                    }
                }
                // 将明细数据按groupPackageId分组
                Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = organizationGroupPackageDetail.stream()
                    .collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
                organizationList.forEach(dto -> {
                    List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
                    dto.setDetailList(details != null ? details : Collections.emptyList());
                });
            }
            ordersGroupPackageUseDto.setOrganizationList(organizationList);
        }

        // 全院组套
        List<OrdersGroupPackageQueryDto> hospitalGroupPackage =
            ordersGroupPackageAppMapper.getGroupPackage(BindingType.HOSPITAL.getValue(), null, null, null);
        if (!hospitalGroupPackage.isEmpty()) {
            List<OrdersGroupPackageDto> hospitalList = hospitalGroupPackage.stream().map(queryDto -> {
                OrdersGroupPackageDto dto = new OrdersGroupPackageDto();
                dto.setGroupPackageId(queryDto.getGroupPackageId());
                dto.setName(queryDto.getName());
                return dto;
            }).collect(Collectors.toList());
            List<Long> groupPackageIds =
                hospitalList.stream().map(OrdersGroupPackageDto::getGroupPackageId).collect(Collectors.toList());
            // 明细项
            List<OrdersGroupPackageDetailQueryDto> hospitalGroupPackageDetail =
                ordersGroupPackageAppMapper.getGroupPackageDetail(groupPackageIds);
            // 明细项赋值
            if (!hospitalGroupPackageDetail.isEmpty()) {
                // 医嘱定义id集合
                List<Long> orderDefinitionIdParamList = hospitalGroupPackageDetail.stream()
                    .map(OrdersGroupPackageDetailQueryDto::getOrderDefinitionId).collect(Collectors.toList());
                // 医嘱下拉详细信息
                List<AdviceBaseDto> personalRecords =
                    iDoctorStationAdviceAppService.getAdviceBaseInfo(null, null, null, orderDefinitionIdParamList,
                        organizationId, 1, 100, Whether.NO.getValue(), List.of(1, 2, 3)).getRecords();
                // 创建AdviceBaseDto的映射，以adviceDefinitionId为key
                Map<Long, AdviceBaseDto> adviceMap = personalRecords.stream().collect(Collectors
                    .toMap(AdviceBaseDto::getAdviceDefinitionId, advice -> advice, (existing, replacement) -> existing // 如果有重复key，保留第一个
                    ));
                // 遍历personalGroupPackageDetail，进行匹配赋值
                for (OrdersGroupPackageDetailQueryDto detail : hospitalGroupPackageDetail) {
                    Long orderDefinitionId = detail.getOrderDefinitionId();
                    if (orderDefinitionId != null) {
                        AdviceBaseDto matchedAdvice = adviceMap.get(orderDefinitionId);
                        if (matchedAdvice != null) {
                            detail.setOrderDetailInfos(matchedAdvice);
                        }
                    }
                }
                // 将明细数据按groupPackageId分组
                Map<Long, List<OrdersGroupPackageDetailQueryDto>> detailMap = hospitalGroupPackageDetail.stream()
                    .collect(Collectors.groupingBy(OrdersGroupPackageDetailQueryDto::getGroupPackageId));
                hospitalList.forEach(dto -> {
                    List<OrdersGroupPackageDetailQueryDto> details = detailMap.get(dto.getGroupPackageId());
                    dto.setDetailList(details != null ? details : Collections.emptyList());
                });
            }
            ordersGroupPackageUseDto.setHospitalList(hospitalList);
        }

        return ordersGroupPackageUseDto;
    }

}
