package thyyxxk.webserver.service.executeItem;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import thyyxxk.webserver.dao.his.executeItem.ExecuteItemDao;
import thyyxxk.webserver.entity.ResultVo;
import thyyxxk.webserver.entity.executeItem.ExecuteItemData;
import thyyxxk.webserver.entity.executeItem.ExecuteItemParam;
import thyyxxk.webserver.entity.executeItem.NumberEnum;
import thyyxxk.webserver.utils.AssertUtil;
import thyyxxk.webserver.utils.CommonUtil;
import thyyxxk.webserver.utils.ResultVoUtil;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description:
 * @Author:lihong
 * @Date: 2023/11/21
 */
@Service
@Slf4j
public class ExecuteItemService {
    @Autowired
    private ExecuteItemDao dao;

    public List<ExecuteItemData> queryExecuteItem(ExecuteItemParam param) {
        dealExecuteItemParam(param);
        //项目
        List<ExecuteItemData> list;
        if(NumberEnum.TWO.getCode().equals(param.getClassCode())){
            list = dao.selectExecuteItemData(param);
        }else {
            list = dao.selectExecuteItem(param);
        }
        if(CollUtil.isNotEmpty(list)){
            list.forEach(item->{
                item.setDrugQuanStr(Convert.toStr(item.getDrugQuan(),"")+Convert.toStr(item.getMiniUnit(),""));
                item.setOrderName(item.getOrderName()+Convert.toStr(item.getSpecification(),""));
            });
            Map<String, List<ExecuteItemData>> groupMap = list.stream().collect(Collectors.groupingBy(item -> item.getInpatientNo().trim() + "_" + Convert.toStr(item.getActOrderNo().toString(), "")));
            List<ExecuteItemData> tempList = new ArrayList<>();
            for(String key : groupMap.keySet()){
                List<String> occTimes = groupMap.get(key).stream().map(item -> DateUtil.format(item.getOccTime(),"HH:mm")).collect(Collectors.toList());
                groupMap.get(key).get(0).setOccTimeStr(CollUtil.join(occTimes," "));
                tempList.add(groupMap.get(key).get(0));
            }
            List<ExecuteItemData> result = new ArrayList<>();
            Map<String, List<ExecuteItemData>> inpatientNoMap = tempList.stream().collect(Collectors.groupingBy(item -> item.getInpatientNo()));
            for(String key : inpatientNoMap.keySet()){
                ExecuteItemData temp = new ExecuteItemData();
                temp.setInpatientNo(inpatientNoMap.get(key).get(0).getInpatientNo());
                temp.setBedNo(inpatientNoMap.get(key).get(0).getBedNo());
                temp.setName(inpatientNoMap.get(key).get(0).getName());
                temp.setShowFlag(0);
                result.add(temp);
                result.addAll(inpatientNoMap.get(key));
            }
            List<ExecuteItemData> collect = result.stream().sorted(Comparator.comparing(item->Convert.toInt(item.getBedNo(),0))).collect(Collectors.toList());
            return collect;
        }
        return list;
    }

    private void dealExecuteItemParam(ExecuteItemParam param) {
        AssertUtil.isnotBlank(param.getWardCode(), "病室不能为空");
        AssertUtil.isnotBlank(param.getExecuteTime(), "执行时间不能为空");
        DateTime date = DateUtil.parseDateTime(param.getExecuteTime());
        param.setEndTime(DateUtil.formatDateTime(DateUtil.offsetDay(date, 1)));
        if (NumberEnum.ZERO.getCode().equals(param.getPageClass())) {
            AssertUtil.isnotBlank(param.getClassCode(), "请选择分类");
            AssertUtil.isnotBlank(param.getCodes(), "请选择分类");
            if (NumberEnum.TWO.getCode().equals(param.getExecuteFlag())) {
                if (NumberEnum.ZERO.getCode().equals(param.getClassCode()) || NumberEnum.ThREE.getCode().equals(param.getClassCode())) {
                    param.setCaseValue("c");
                } else if (NumberEnum.ONE.getCode().equals(param.getClassCode())) {
                    param.setCaseValue("x");

                } else if (NumberEnum.TWO.getCode().equals(param.getClassCode())) {
                    if ("#".equals(param.getItemCode())) {
                    //药品
                        param.setCaseValue("yp");
                    } else {
                        param.setCaseValue("xm");
                    }
                }
                List<String> codes = param.getCodes().stream().map(item -> Convert.toStr(item.get("code"), "")).collect(Collectors.toList());
                param.setCodeCondition(CommonUtil.toInStringSql(codes));

            } else {
                List<String> codes = param.getCodes().stream().map(item -> Convert.toStr(item.get("code"), "")).collect(Collectors.toList());
                param.setCodeCondition(CommonUtil.toInStringSql(codes));
            }
        } else {
            param.setClassCode(null);
            param.setCodes(null);
            if (NumberEnum.TWO.getCode().equals(param.getExecuteFlag())) {
                param.setCaseValue("a");
                param.setCodeCondition("'a','ZL'");
            }
        }
    }
    @Transactional(rollbackFor = Exception.class)
    public ResultVo<String> updateExecuteItemPrintFlag(List<ExecuteItemData> param) {
         AssertUtil.isnotBlank(param,"打印数据不能为空!");
        List<ExecuteItemData> collect = param.stream().filter(item -> item.getShowFlag() == 1).collect(Collectors.toList());
        List<ExecuteItemData> collect1 = collect.stream().filter(item -> StrUtil.isBlank(item.getPrintFlag())).collect(Collectors.toList());
        if(CollUtil.isNotEmpty(collect1)){
            Map<String, List<ExecuteItemData>> inpatientNoGroup = collect1.stream().collect(Collectors.groupingBy(item -> item.getInpatientNo()));
            for(String key : inpatientNoGroup.keySet()){
                List<ExecuteItemData> executeItemData = inpatientNoGroup.get(key);
                List<BigDecimal> actOrderNos = executeItemData.stream().map(item -> item.getActOrderNo()).collect(Collectors.toList());
                List<List<BigDecimal>> split = CollUtil.split(actOrderNos, 50);
                for(List<BigDecimal> item: split){
                    String actOrderNoCondition = CollUtil.join(item, ",");
                    dao.updaYzActOccPrintFlag(key.trim(),actOrderNoCondition);
                }
            }
        }
      return   ResultVoUtil.success();
    }

    public List<ExecuteItemData> queryExecuteItemDetail(ExecuteItemParam param) {
        dealExecuteItemParam(param);
        List<ExecuteItemData> list = dao.selectExecuteItemDetail(param);
        if(CollUtil.isNotEmpty(list)){
            List<ExecuteItemData> orderNameEmpty = list.stream().filter(item -> StrUtil.isBlank(item.getOrderName())).collect(Collectors.toList());
            List<ExecuteItemData> OrderNoList = null;
            if(CollUtil.isNotEmpty(orderNameEmpty)){
                Set<BigDecimal> actOrderNo = orderNameEmpty.stream().map(ExecuteItemData::getActOrderNo).collect(Collectors.toSet());
                if(CollUtil.isNotEmpty(actOrderNo)){
                     OrderNoList =  dao.selectOrderName(CollUtil.join(actOrderNo,","));
                }
            }
            Map<BigDecimal, List<ExecuteItemData>> collect = null;
            if(CollUtil.isNotEmpty(OrderNoList)){
                collect = OrderNoList.stream().collect(Collectors.groupingBy(ExecuteItemData::getActOrderNo));
            }
            for(ExecuteItemData item:list){
                if(CollUtil.isNotEmpty(collect)){
                    List<ExecuteItemData> executeItemData = collect.get(item.getActOrderNo());
                    if(CollUtil.isNotEmpty(executeItemData) && StrUtil.isBlank(item.getOrderName())){
                        item.setOrderName(executeItemData.get(0).getOrderName());
                    }
                }
                item.setOrderName(item.getOrderName()+(StrUtil.isBlank(item.getSpecification()) || item.getSpecification().equals("诊疗项目") ?"" :item.getSpecification()));
                item.setOccTimeStr(DateUtil.format(item.getOccTime(),"MM-dd :HH:mm"));
            }
        }
        return list;
    }
}
