package com.xinelu.manage.service.specialdiseasenode.impl;

import com.alibaba.fastjson2.JSONObject;
import com.xinelu.common.core.domain.AjaxResult;
import com.xinelu.common.enums.PatientSexEnum;
import com.xinelu.common.exception.ServiceException;
import com.xinelu.common.utils.BaseUtil;
import com.xinelu.common.utils.SecurityUtils;
import com.xinelu.common.utils.bean.BeanUtils;
import com.xinelu.manage.domain.patientinfo.PatientAllInfoView;
import com.xinelu.manage.domain.patientnodeparamscurrent.PatientNodeParamsCurrent;
import com.xinelu.manage.domain.specialdiseasenode.SpecialDiseaseNode;
import com.xinelu.manage.domain.specialdiseaseroute.SpecialDiseaseRoute;
import com.xinelu.manage.mapper.patientinfo.PatientInfoMapper;
import com.xinelu.manage.mapper.patientnodeparamslcurrent.PatientNodeParamsCurrentMapper;
import com.xinelu.manage.mapper.specialdiseasenode.SpecialDiseaseNodeMapper;
import com.xinelu.manage.mapper.specialdiseaseroute.SpecialDiseaseRouteMapper;
import com.xinelu.manage.service.patientinfo.IPatientAllInfoViewService;
import com.xinelu.manage.service.signpatientmanageroutenode.ISignPatientManageRouteNodeService;
import com.xinelu.manage.service.specialdiseasenode.ISpecialDiseaseNodeService;
import com.xinelu.manage.vo.specialdiseasenode.RouteTaskAuditVo;
import com.xinelu.manage.vo.specialdiseasenode.SpecialDiseaseNodeVO;
import com.xinelu.manage.vo.specialdiseaseroute.SpecialDiseaseRouteVO;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.TreeSet;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 专病路径-管理节点信息Service业务层处理
 *
 * @author xinelu
 * @date 2024-03-13
 */
@Slf4j
@Service
public class SpecialDiseaseNodeServiceImpl implements ISpecialDiseaseNodeService {
    @Resource
    private SpecialDiseaseNodeMapper specialDiseaseNodeMapper;
    @Resource
    private SpecialDiseaseRouteMapper specialDiseaseRouteMapper;
    @Resource
    private PatientNodeParamsCurrentMapper patientNodeParamsCurrentMapper;
    @Resource
    private PatientInfoMapper patientInfoMapper;
    @Resource
    private IPatientAllInfoViewService patientAllInfoViewService;
	@Resource
	private ISignPatientManageRouteNodeService signPatientManageRouteNodeService;


    /**
     * 查询专病路径-管理节点信息
     *
     * @param id 专病路径-管理节点信息主键
     * @return 专病路径-管理节点信息
     */
    @Override
    public SpecialDiseaseNode selectSpecialDiseaseNodeById(Long id) {
        return specialDiseaseNodeMapper.selectSpecialDiseaseNodeById(id);
    }

    /**
     * 查询专病路径-管理节点信息列表
     *
     * @param specialDiseaseNode 专病路径-管理节点信息
     * @return 专病路径-管理节点信息
     */
    @Override
    public List<SpecialDiseaseNode> selectSpecialDiseaseNodeList(SpecialDiseaseNode specialDiseaseNode) {
        return specialDiseaseNodeMapper.selectSpecialDiseaseNodeList(specialDiseaseNode);
    }

    /**
     * 新增专病路径-管理节点信息
     *
     * @param specialDiseaseNode 专病路径-管理节点信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult insertSpecialDiseaseNode(SpecialDiseaseRouteVO specialDiseaseNode) {
        SpecialDiseaseRoute specialDiseaseRoute = new SpecialDiseaseRoute();
        BeanUtils.copyBeanProp(specialDiseaseRoute, specialDiseaseNode);
        specialDiseaseRoute.setCreateTime(LocalDateTime.now());
        specialDiseaseRoute.setCreateBy(SecurityUtils.getUsername());
        int insertRouteCount = specialDiseaseRouteMapper.insertSpecialDiseaseRoute(specialDiseaseRoute);
        if (insertRouteCount < 0) {
            throw new ServiceException("新增专病路径管理节点信息失败");
        }
        for (SpecialDiseaseNode diseaseNode : specialDiseaseNode.getSpecialDiseaseNodeList()) {
            diseaseNode.setRouteId(specialDiseaseRoute.getId());
            diseaseNode.setCreateTime(LocalDateTime.now());
            diseaseNode.setCreateBy(SecurityUtils.getUsername());
        }
        int insertNodeCount = specialDiseaseNodeMapper.insertSpecialDiseaseNodeList(specialDiseaseNode.getSpecialDiseaseNodeList());
        if (insertNodeCount < 0) {
            throw new ServiceException("新增专病路径管理节点信息失败");
        }
        return AjaxResult.success();
    }

    /**
     * 修改专病路径-管理节点信息
     *
     * @param specialDiseaseNode 专病路径-管理节点信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateSpecialDiseaseNode(SpecialDiseaseRouteVO specialDiseaseNode) {

        //if (Objects.nonNull(specialDiseaseNode) && Objects.nonNull(specialDiseaseNode.getSpecialDiseaseRouteId())) {
        //    SpecialDiseaseRoute specialDiseaseRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseNode.getSpecialDiseaseRouteId());
        //    if (specialDiseaseRoute.getParentRouteId() == null || specialDiseaseRoute.getParentRouteId() == 0) {
        //        if (Objects.nonNull(specialDiseaseRoute) && StringUtils.isNotBlank(specialDiseaseRoute.getReleaseStatus()) && !ReleaseStatusEnum.UNPUBLISHED.getInfo().equals(specialDiseaseRoute.getReleaseStatus())) {
        //            return AjaxResult.error("已发布过的专病路径不能修改！");
        //        }
        //    } else {
        //        // 判断主路径的发布状态
        //        SpecialDiseaseRoute parentRoute = specialDiseaseRouteMapper.selectSpecialDiseaseRouteById(specialDiseaseRoute.getParentRouteId());
        //        if (Objects.nonNull(parentRoute) && StringUtils.isNotBlank(parentRoute.getReleaseStatus()) && !StringUtils.equals(ReleaseStatusEnum.UNPUBLISHED.getInfo(), specialDiseaseRoute.getReleaseStatus())) {
        //            return AjaxResult.error("已发布过的专病路径不能修改！");
        //        }
        //    }
        //}
        List<Long> oldIds = specialDiseaseNodeMapper.selectSpecialDiseaseRouteIds(specialDiseaseNode.getSpecialDiseaseRouteId());

        SpecialDiseaseRoute specialDiseaseRoute = new SpecialDiseaseRoute();
        BeanUtils.copyBeanProp(specialDiseaseRoute, specialDiseaseNode);
        specialDiseaseRoute.setUpdateTime(LocalDateTime.now());
        specialDiseaseRoute.setUpdateBy(SecurityUtils.getUsername());
        specialDiseaseRoute.setId(specialDiseaseNode.getSpecialDiseaseRouteId());
        int updateRouteCount = specialDiseaseRouteMapper.updateSpecialDiseaseRoute(specialDiseaseRoute);
        if (updateRouteCount < 0) {
            log.info("修改专病路径失败");
            throw new ServiceException("修改专病路径管理节点信息失败");
        }

	    List<SpecialDiseaseNodeVO> diseaseNodeList = specialDiseaseNode.getSpecialDiseaseNodeList();
	    if (CollectionUtils.isEmpty(diseaseNodeList)) {
	        return AjaxResult.success();
	    }
	    // 循环节点查找新增、删除、修改的节点
	    List<SpecialDiseaseNodeVO> insertList = new ArrayList<>();
	    List<SpecialDiseaseNodeVO> updateList = new ArrayList<>();
	    diseaseNodeList.forEach(diseaseNode -> {
		    if (StringUtils.isBlank(diseaseNode.getRouteNodeName())) {
			    throw new ServiceException("请输入节点名称");
		    }
		    if (diseaseNode.getRouteNodeDay() == null) {
			    throw new ServiceException("请输入节点时间");
		    }
		    if (StringUtils.isBlank(diseaseNode.getTaskType()) || StringUtils.isBlank(diseaseNode.getTaskSubdivision())) {
			    throw new ServiceException("任务类型、任务细分不能为空");
		    }
			if (diseaseNode.getSpecialDiseaseNodeId() == null) {
				// 新增的节点
				insertList.add(diseaseNode);
			} else {
				// 修改的节点
				updateList.add(diseaseNode);
			}
	    });
	    List<Long> ids = diseaseNodeList.stream().map(SpecialDiseaseNodeVO::getSpecialDiseaseNodeId).collect(Collectors.toList());
		// ids与oldIds对比，oldIds中包含ids中不包含的为删除的节点，其余为修改的节点
	    List<Long> deleteList = oldIds.stream().filter(item -> !ids.contains(item)).collect(Collectors.toList());
	    // 删除节点
		if (CollectionUtils.isNotEmpty(deleteList)) {
			int deleteCount = specialDiseaseNodeMapper.deleteSpecialDiseaseNodeByIds(deleteList.toArray(new Long[0]));
			if (deleteCount < 0) {
				log.info("删除管理节点信息失败");
			    throw new ServiceException("修改专病路径管理节点信息失败");
			}
		}
		// 新增节点
	    if (CollectionUtils.isNotEmpty(insertList)) {
		    List<SpecialDiseaseNodeVO> specialDiseaseNodeVOS = new ArrayList<>();
		    insertList.forEach(diseaseNode -> {
			    diseaseNode.setRouteId(specialDiseaseRoute.getId());
			    diseaseNode.setRouteName(specialDiseaseNode.getRouteName());
			    diseaseNode.setCreateTime(LocalDateTime.now());
			    diseaseNode.setCreateBy(SecurityUtils.getUsername());
			    specialDiseaseNodeVOS.add(diseaseNode);
		    });
		    int insertNodeCount = specialDiseaseNodeMapper.insertSpecialDiseaseNodeList(specialDiseaseNodeVOS);
		    if (insertNodeCount < 0) {
			    log.info("新增管理节点信息失败");
			    throw new ServiceException("修改专病路径管理节点信息失败");
		    }
	    }
		// 修改节点
	    if (CollectionUtils.isNotEmpty(updateList)) {
		    updateList.forEach(diseaseNode -> {
			    diseaseNode.setRouteId(specialDiseaseRoute.getId());
			    diseaseNode.setRouteName(specialDiseaseNode.getRouteName());
			    diseaseNode.setUpdateTime(LocalDateTime.now());
			    diseaseNode.setUpdateBy(SecurityUtils.getUsername());
			    diseaseNode.setId(diseaseNode.getSpecialDiseaseNodeId());
			    int flag = specialDiseaseNodeMapper.updateSpecialDiseaseNode(diseaseNode);
			    if (flag < 0) {
				    log.info("修改管理节点信息失败");
				    throw new ServiceException("修改专病路径管理节点信息失败");
			    }
		    });
	    }
		// 修改任务表
	    signPatientManageRouteNodeService.updateBySpecialDiseaseRoute(deleteList, updateList, insertList);
        return AjaxResult.success();
    }

    /**
     * 批量删除专病路径-管理节点信息
     *
     * @param ids 需要删除的专病路径-管理节点信息主键
     * @return 结果
     */
    @Override
    public int deleteSpecialDiseaseNodeByIds(Long[] ids) {
        return specialDiseaseNodeMapper.deleteSpecialDiseaseNodeByIds(ids);
    }

    /**
     * 删除专病路径-管理节点信息信息
     *
     * @param id 专病路径-管理节点信息主键
     * @return 结果
     */
    @Override
    public int deleteSpecialDiseaseNodeById(Long id) {
        return specialDiseaseNodeMapper.deleteSpecialDiseaseNodeById(id);
    }

    /**
     * 查询专病路径-管理节点信息列表
     *
     * @param specialDiseaseRouteId 路径id
     * @return AjaxResult
     */
    @Override
    public AjaxResult selectSpecialDisease(Long specialDiseaseRouteId) {
        return AjaxResult.success(specialDiseaseNodeMapper.selectSpecialDiseaseByRouteId(specialDiseaseRouteId));
    }

    /**
     * 修改节点信息状态
     *
     * @param specialDiseaseNode 节点信息
     * @return AjaxResult
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public AjaxResult updateRouteCheckStatus(SpecialDiseaseNode specialDiseaseNode) {
        if (Objects.isNull(specialDiseaseNode) || Objects.isNull(specialDiseaseNode.getId())) {
            return AjaxResult.error("请选择需要审核的信息！");
        }
        specialDiseaseNode.setRouteCheckDate(LocalDateTime.now());
        return AjaxResult.success(specialDiseaseNodeMapper.updateSpecialDiseaseNode(specialDiseaseNode));
    }

    @Override
    public List<List<PatientNodeParamsCurrent>> getParams(Long id, Long patientId) {
        List<List<PatientNodeParamsCurrent>> retList = new ArrayList<>();
        // 根据节点id查询是否有已经维护的参数
        PatientNodeParamsCurrent paramsQuery = new PatientNodeParamsCurrent();
        paramsQuery.setPatientId(patientId);
        paramsQuery.setRouteNodeId(id);
        List<PatientNodeParamsCurrent> nodeParams = patientNodeParamsCurrentMapper.selectPatientNodeParamsCurrentList(paramsQuery);

        // 查询SpecialDiseaseNode中包含的可编辑标签
        List<PatientNodeParamsCurrent> diseaseNodeParams = new ArrayList<>();
        SpecialDiseaseNode specialDiseaseNode = specialDiseaseNodeMapper.selectSpecialDiseaseNodeById(id);
        if (StringUtils.isNotBlank(specialDiseaseNode.getNodeContent()) && specialDiseaseNode.getNodeContent().contains("data-fieldMark")) {
            JSONObject paramValues = getParamsValue(patientId);
            Document document = Jsoup.parse(specialDiseaseNode.getNodeContent());
            // 需要提取的span
            Elements spanlist = document.select("span[data-w-e-type]");
            for (Element span : spanlist) {
                PatientNodeParamsCurrent nodeParamCurrent = new PatientNodeParamsCurrent();
                String paramKey = span.attr("data-fieldMark");
                String paramName = span.attr("data-fileSpan");
                nodeParamCurrent.setSn("1");
                nodeParamCurrent.setParamName(paramName);
                nodeParamCurrent.setParamKey(paramKey);
                nodeParamCurrent.setParamValue(paramValues.getOrDefault(paramKey, "").toString());
                diseaseNodeParams.add(nodeParamCurrent);
            }
            // nodeParams去重
            diseaseNodeParams = diseaseNodeParams.stream().collect(Collectors.collectingAndThen(Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(PatientNodeParamsCurrent::getParamKey))), ArrayList::new));
        }
        // 之前未维护过参数专病路径节点中的参数为返回值
        if (CollectionUtils.isEmpty(nodeParams)) {
            retList.add(diseaseNodeParams);
        } else {
            // 之前维护过参数则将参数进行对比
            Map<String, List<PatientNodeParamsCurrent>> groupBySn = nodeParams.stream().collect(Collectors.groupingBy(PatientNodeParamsCurrent::getSn));
            for (String sn : groupBySn.keySet()) {
                List<PatientNodeParamsCurrent> oldParams = groupBySn.get(sn);
                retList.add(oldParams);
            }
        }
        return retList;
    }

    @Override
    public List<RouteTaskAuditVo> getByParentRouteId(Long parentRouteId) {
        return specialDiseaseNodeMapper.getByParentRouteId(parentRouteId);
    }

    /**
     * 根据任务细分类型获取患者的真实信息
     *
     * @param patientId 患者主键
     * @return 实际信息
     */
    private JSONObject getParamsValue(Long patientId) {
        JSONObject retObj = new JSONObject();
        PatientAllInfoView patientAllInfoView = patientAllInfoViewService.selectPatientAllInfoViewByPatientId(patientId);
        if (ObjectUtils.isEmpty(patientAllInfoView)) {
            throw new ServiceException("患者信息获取错误，请联系管理员!");
        }
        retObj = JSONObject.parseObject(JSONObject.toJSONString(patientAllInfoView));
        // 性别转换成中文、计算年龄
        retObj.fluentPut("sex", PatientSexEnum.getInfoByCode(patientAllInfoView.getSex()).getInfo())
                .fluentPut("age", BaseUtil.getAge(patientAllInfoView.getBirthDate()));
        return retObj;
    }
}
