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

import java.util.*;
import java.util.stream.Collectors;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.core.common.core.domain.R;
import com.core.common.utils.AssignSeqUtil;
import com.core.common.utils.ChineseConvertUtils;
import com.core.common.utils.MessageUtils;
import com.core.common.utils.StringUtils;
import com.openhis.administration.domain.BodyStructure;
import com.openhis.administration.service.IBodyStructureService;
import com.openhis.common.constant.CommonConstants;
import com.openhis.common.constant.PromptMsgConstant;
import com.openhis.common.enums.AssignSeqEnum;
import com.openhis.common.enums.PublicationStatus;
import com.openhis.common.utils.EnumUtils;
import com.openhis.web.basedatamanage.appservice.IBodyStructureAppService;
import com.openhis.web.basedatamanage.dto.BodyStructureDto;

@Service
public class BodyStructureAppServiceImpl implements IBodyStructureAppService {

    @Resource
    private IBodyStructureService bodyStructureService;

    @Resource
    private AssignSeqUtil assignSeqUtil;

    @Override
    public Page<BodyStructureDto> getBodyStructureTree(Integer pageNo, Integer pageSize, HttpServletRequest request) {
        // 查询身体部位列表
        Page<BodyStructure> page = bodyStructureService.page(new Page<>(pageNo, pageSize));
        List<BodyStructure> bodyStructureList = page.getRecords();
        // 将身体部位列表转为树结构
        List<BodyStructureDto> orgTree = buildTree(bodyStructureList);
        Page<BodyStructureDto> orgQueryDtoPage = new Page<>(pageNo, pageSize, page.getTotal());
        orgQueryDtoPage.setRecords(orgTree);
        return orgQueryDtoPage;
    }

    /**
     * 将身体部位列表转换为树结构
     *
     * @param records 机构列表
     * @return tree
     */
    private List<BodyStructureDto> buildTree(List<BodyStructure> records) {
        // 按b_no的层级排序，确保父节点先处理
        List<BodyStructure> sortedRecords = records.stream()
            .sorted(Comparator.comparingInt(r -> r.getBusNo().split("\\.").length)).collect(Collectors.toList());

        Map<String, BodyStructureDto> nodeMap = new HashMap<>();
        List<BodyStructureDto> tree = new ArrayList<>();

        for (BodyStructure record : sortedRecords) {
            String bNo = record.getBusNo();
            String[] parts = bNo.split("\\.");
            BodyStructureDto node = new BodyStructureDto();
            BeanUtils.copyProperties(record, node);
            node.setStatusEnum_enumText(EnumUtils.getInfoByValue(PublicationStatus.class, node.getStatusEnum()));

            // 将当前节点加入映射
            nodeMap.put(bNo, node);

            if (parts.length == 1) {
                // 根节点
                tree.add(node);
            } else {
                // 获取父节点的b_no（去掉最后一部分）
                String parentBNo = String.join(".", Arrays.copyOf(parts, parts.length - 1));
                BodyStructureDto parent = nodeMap.get(parentBNo);

                if (parent != null) {
                    parent.getChildren().add(node);
                } else {
                    // 处理父节点不存在的情况（例如数据缺失）
                    // 可根据需求调整为将节点加入根或抛出异常
                }
            }
        }
        return tree;
    }

    /**
     * 身体部位信息详情
     *
     * @param id 身体部位id
     * @return 机构信息详情
     */
    @Override
    public R<?> getBodyStructureInfo(Long id) {
        BodyStructure bodyStructure = bodyStructureService.getById(id);
        return R.ok(bodyStructure,
            MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"身体部位信息查询"}));
    }

    /**
     * 添加/编辑部位
     *
     * @param bodyStructureDto 身体部位信息
     * @return 操作结果
     */
    @Override
    public R<?> addOrEditBodyStructure(BodyStructureDto bodyStructureDto) {

        // 新增身体部位信息
        BodyStructure bodyStructure = new BodyStructure();
        BeanUtils.copyProperties(bodyStructureDto, bodyStructure);

        // 拼音码
        bodyStructure.setPyStr(ChineseConvertUtils.toPinyinFirstLetter(bodyStructureDto.getName()));
        // 五笔码
        bodyStructure.setWbStr(ChineseConvertUtils.toWBFirstLetter(bodyStructureDto.getName()));

        if (bodyStructureDto.getId() != null) {
            // 更新身体部位信息
            bodyStructureService.updateById(bodyStructure);
        } else {
            bodyStructure.setStatusEnum(PublicationStatus.ACTIVE.getValue());
            // 采番bus_no三位
            String code = assignSeqUtil.getSeq(AssignSeqEnum.BODY_STRUCTURE_NO.getPrefix(), 3);
            // 如果传了上级部位 把当前的code拼到后边
            if (StringUtils.isNotEmpty(bodyStructure.getBusNo())) {
                bodyStructure.setBusNo(String.format(CommonConstants.Common.MONTAGE_FORMAT, bodyStructure.getBusNo(),
                    CommonConstants.Common.POINT, code));
            } else {
                bodyStructure.setBusNo(code);
            }
            // 生成待发送的机构信息
            bodyStructureService.save(bodyStructure);
        }
        // 返回身体部位id
        return R.ok(bodyStructure.getId(),
            MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"身体部位信息更新添加"}));
    }

    /**
     * 删除身体部位
     *
     * @param id 身体部位id
     * @return 操作结果
     */
    @Override
    public R<?> deleteBodyStructure(String id) {

        List<Long> orgIdList = new ArrayList<>();
        if (id != null) {
            orgIdList = Arrays.stream(id.split(",")).map(Long::parseLong).collect(Collectors.toList());
        }

        // 删除身体部位信息
        boolean deleteOrgSuccess = bodyStructureService.removeByIds(orgIdList);
        return deleteOrgSuccess
            ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00005, new Object[] {"身体部位信息"}))
            : R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, new Object[] {"身体部位信息"}));
    }

    /**
     * 身体部位列表启用
     *
     * @param id 身体部位列表信息id
     * @return 操作结果
     */
    @Override
    public R<?> activeBodyStructure(Long id) {
        // 机构启用
        boolean result = bodyStructureService.activeBodyStructure(id);
        return result
            ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"身体部位信息启用"}))
            : R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, new Object[] {"身体部位信息启用"}));
    }

    /**
     * 身体部位列表停用
     *
     * @param id 身体部位列表信息id
     * @return 操作结果
     */
    @Override
    public R<?> inactiveBodyStructure(Long id) {
        // 机构停用
        boolean result = bodyStructureService.inactiveBodyStructure(id);
        return result
            ? R.ok(null, MessageUtils.createMessage(PromptMsgConstant.Common.M00004, new Object[] {"身体部位信息停用"}))
            : R.fail(MessageUtils.createMessage(PromptMsgConstant.Common.M00007, new Object[] {"身体部位信息停用"}));
    }

}
