package com.kcim.service.impl;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kcim.common.constants.NumberConstant;
import com.kcim.common.constants.SQLParameter;
import com.kcim.common.enums.CustomSqlTypeEnum;
import com.kcim.common.enums.ReportItemTypeEnum;
import com.kcim.common.util.BeanUtil;
import com.kcim.common.util.PageUtils;
import com.kcim.dao.model.ComputePatientCostDetail;
import com.kcim.dao.model.dto.ComputeItemGroupByVisitNoDto;
import com.kcim.dao.model.dto.ComputePatientCostPageDto;
import com.kcim.dao.repository.ComputeItemCostRepository;
import com.kcim.dao.repository.ComputePatientCostDetailRepository;
import com.kcim.dao.repository.ComputePatientCostRepository;
import com.kcim.dao.repository.ImportPatientInfoRepository;
import com.kcim.service.ComputeItemCostService;
import com.kcim.service.ComputePatientCostService;
import com.kcim.service.SqlService;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.util.*;

/**
 * @program: CostAccount
 * @description: 病人成本计算接口实现类
 * @author: Wang.YS
 * @create: 2023-10-30 16:15
 **/
@Service("ComputePatientCostService")
@AllArgsConstructor
@Slf4j
public class ComputePatientCostServiceImpl implements ComputePatientCostService {
    /**
     * 病人成本计算主表
     */
    ComputePatientCostRepository repository;
    /**
     * 病人成本计算明细表
     */
    ComputePatientCostDetailRepository detailRepository;
    /**
     * 患者导入信息
     */
    ImportPatientInfoRepository importPatientInfoRepository;
    /**
     * 收费项目成本计算
     */
    ComputeItemCostRepository computeItemCostRepository;

    ComputeItemCostService computeItemCostService;
    SqlService sqlService;

    /**
     * 成本核算-病人成本计算-获取列表
     *
     * @param current        当前页
     * @param pageSize       页容量
     * @param computeDate    核算年月
     * @param departmentName 科室名称
     * @param patientName    患者姓名
     * @return 列表
     */
    @Override
    public Object patientCostCalculateList(Integer current, Integer pageSize, String computeDate, String departmentName, String patientName) {
        Page<ComputePatientCostPageDto> page = repository.getByPage(current, pageSize, computeDate, departmentName, patientName);
        if(CollectionUtils.isEmpty(page.getRecords())){
            return new PageUtils(new ArrayList<>(), NumberConstant.ZERO,pageSize,current);
        }
        return new PageUtils(page.getRecords(), Math.toIntExact(page.getTotal()),pageSize,current);
    }

    /**
     * 成本核算-病人成本计算-计算
     *
     * @param computeDate 核算年月
     */
    @Override
    @Transactional(rollbackFor = Exception.class,propagation = Propagation.REQUIRED)
    public void patientCostCalculate(String computeDate) {
        Map<String,String> sqlParameter = new HashMap<>();
        sqlParameter.put(SQLParameter.COMPUTE_DATE_CODE,computeDate);
        sqlService.autoExecuteSql(CustomSqlTypeEnum.PT_COST_CALC.getCode(),sqlParameter);
/*      暂时更换成自定义sql 执行 下面代码留用
        try {
            //获取导入的患者信息
            List<ImportPatientInfo> patientInfos = importPatientInfoRepository.getByComputeDate(computeDate);
            if(CollectionUtils.isEmpty(patientInfos)){
                log.error("未导入当前核算年月【"+computeDate+"】患者信息，计算中止");
                throw new CostException("未导入当前核算年月【"+computeDate+"】患者信息，当前计算中止");
            }
            //获取计算过的项目信息
            List<ComputeItemGroupByVisitNoDto> itemCost = computeItemCostRepository.getByComputeDateGroupByVisitNo(computeDate);
            if(CollectionUtils.isEmpty(itemCost)){
                throw new CostException("当前核算年月【"+computeDate+"】未计算收费项目成本信息，请先计算收费项目成本，当前计算中止");
            }
            Map<String,ComputeItemGroupByVisitNoDto> computeItemGroup = itemCost.stream().collect(Collectors.toMap(ComputeItemGroupByVisitNoDto::getVisitNo, dto -> dto, (a, b) -> b));

            ComputePatientCost computePatientCost = new ComputePatientCost();
            computePatientCost.setComputeDate(computeDate);
            computePatientCost.setHospId(UserContext.getHospId());
            computePatientCost.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            computePatientCost.setCreateTime(new Date());
            ComputePatientCostDetail patientCostDetail = new ComputePatientCostDetail();
            patientCostDetail.setHospId(UserContext.getHospId());
            patientCostDetail.setCreateUser(String.valueOf(UserContext.getCurrentUser().getId()));
            patientCostDetail.setCreateTime(new Date());
            List<ComputePatientCost> savePatientCost = new ArrayList<>();
            List<ComputePatientCostDetail> details = new ArrayList<>();
            for (int i = 0; i < patientInfos.size(); i++) {
                ImportPatientInfo info = patientInfos.get(i);
                ComputePatientCost patientCost = BeanUtil.convertObj(computePatientCost, ComputePatientCost.class);
                patientCost.setVisitNo(info.getVisitNo());
                patientCost.setPatientNo(info.getPatientNo());
                patientCost.setName(info.getName());
                patientCost.setDepartmentCode(info.getDepartmentCode());
                patientCost.setDepartmentName(info.getDepartmentName());
                patientCost.setIndex(i);
                List<ComputePatientCostDetail> detail = getDetail(i, patientCostDetail, computeItemGroup.get(info.getVisitNo()));
                savePatientCost.add(patientCost);
                details.addAll(detail);
            }
            if(!CollectionUtils.isEmpty(savePatientCost)){
                //作废当前核算年月已有数据
                List<Integer> integers = repository.removeByComputeDate(computeDate);
                if(!CollectionUtils.isEmpty(integers)){
                    detailRepository.removeByPatientCostId(integers);
                }
                repository.saveBatch(savePatientCost,100);
                if(!CollectionUtils.isEmpty(savePatientCost)){
                    Map<Integer,Integer> indexId = savePatientCost.stream().collect(Collectors.toMap(ComputePatientCost::getIndex, ComputePatientCost::getId, (a, b) -> b));
                    Map<Integer, List<ComputePatientCostDetail>> collect = details.stream().collect(Collectors.groupingBy(ComputePatientCostDetail::getIndex));
                    List<ComputePatientCostDetail> saveCostDetails = new ArrayList<>();
                    collect.keySet().forEach(integer -> {
                        Integer costId = indexId.get(integer);
                        List<ComputePatientCostDetail> detailList = collect.get(integer);
                        detailList.forEach(detail -> detail.setPatientCostId(costId));
                        saveCostDetails.addAll(detailList);
                    });
                    detailRepository.saveBatch(saveCostDetails,500);
                }
            }
        }catch (Exception e){
            log.error(e.getMessage());
            throw new CostException(e.getMessage());
        }
*/

    }

    private List<ComputePatientCostDetail> getDetail(int i, ComputePatientCostDetail patientCostDetail, ComputeItemGroupByVisitNoDto dto) {
        List<String> itemTypeList = computeItemCostService.getItemTypeList();
        List<ComputePatientCostDetail> details = new ArrayList<>();
        for (String s : itemTypeList) {
            ComputePatientCostDetail detail = BeanUtil.convertObj(patientCostDetail, ComputePatientCostDetail.class);
            detail.setType(s);
            detail.setIndex(i);
            if(Objects.nonNull(dto)){
                if(s.equals(ReportItemTypeEnum.DRUG_INCOME.getCode())){
                    detail.setComputeResult(dto.getDrugIncome());
                }else if (s.equals(ReportItemTypeEnum.MATERIAL_INCOME.getCode())) {
                    detail.setComputeResult(dto.getMaterialIncome());
                }else if (s.equals(ReportItemTypeEnum.ITEM_INCOME.getCode())) {
                    detail.setComputeResult(dto.getItemIncome());
                }else if (s.equals(ReportItemTypeEnum.DRUG_COST.getCode())) {
                    detail.setComputeResult(dto.getDrugCost());
                }else if (s.equals(ReportItemTypeEnum.MATERIAL_COST.getCode())) {
                    detail.setComputeResult(dto.getMaterialCost());
                }else if (s.equals(ReportItemTypeEnum.ITEM_COST.getCode())) {
                    detail.setComputeResult(dto.getItemCost());
                }else if (s.equals(ReportItemTypeEnum.EMP_COST.getCode())) {
                    detail.setComputeResult(dto.getEmpCost());
                }else if (s.equals(ReportItemTypeEnum.EQUIPMENT_COST.getCode())) {
                    detail.setComputeResult(dto.getEquipmentCost());
                }else if (s.equals(ReportItemTypeEnum.SPACE_COST.getCode())) {
                    detail.setComputeResult(dto.getSpaceCost());
                }  else {
                    detail.setComputeResult(BigDecimal.ZERO);

                }
            }else {
                detail.setComputeResult(BigDecimal.ZERO);

            }

            details.add(detail);
        }
        return details;
    }







}
