package cn.iocoder.yudao.module.mes.service.devicetype;

import cn.iocoder.yudao.framework.common.util.collection.CollectionUtils;
import cn.iocoder.yudao.module.mes.controller.admin.devicetype.vo.DeviceTypeTreeRespVO;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;


import org.springframework.validation.annotation.Validated;
import org.springframework.transaction.annotation.Transactional;

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

import cn.iocoder.yudao.module.mes.controller.admin.devicetype.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.devicetype.DeviceTypeDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.mes.dal.mysql.devicetype.DeviceTypeMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;


/**
 * 设备类型 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class DeviceTypeServiceImpl implements DeviceTypeService {

    @Resource
    private DeviceTypeMapper deviceTypeMapper;

    @Resource
    private DeviceLedgerMapper deviceLedgerMapper;

    @Override
    public Long createDeviceType(DeviceTypeSaveReqVO createReqVO) {


        // 1. 验证父级设备类型是否存在以及编码是否唯一
        validateParentDeviceType(Long.valueOf(createReqVO.getParentId()));

        validateCodeOnly(createReqVO.getCode());

        // 2. 插入
        DeviceTypeDO deviceType = BeanUtils.toBean(createReqVO, DeviceTypeDO.class);

        // 3. 设置父级链
        if (createReqVO.getParentId() != null && createReqVO.getParentId() > 0) {
            DeviceTypeDO parent = getDeviceType(Long.valueOf(createReqVO.getParentId()));
            deviceType.setParentChain(buildParentChain(parent));
        } else {
            deviceType.setParentChain(""); // 根节点
        }

        deviceTypeMapper.insert(deviceType);

        // 4. 更新子节点的父级链（如果有的话）
        updateChildrenParentChain(deviceType);

        return deviceType.getId();
    }

    private void validateCodeOnly( String code) {
        if (deviceTypeMapper.exists(Wrappers.<DeviceTypeDO>lambdaQuery()
                .eq(DeviceTypeDO::getCode, code))) {
            throw exception(DEVICE_LEDGER_CODE_NOT_ONLY);
        }
    }

    @Override
    public void updateDeviceType(DeviceTypeSaveReqVO updateReqVO) {
        // 1. 校验存在
        DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(updateReqVO.getId());
        validateDeviceTypeExists(deviceTypeDO);
        //编码重复判断
        Long count = deviceTypeMapper.selectCount(new LambdaQueryWrapper<DeviceTypeDO>()
                .eq(DeviceTypeDO::getCode, updateReqVO.getCode())
                .ne(DeviceTypeDO::getId, updateReqVO.getId())

        );

        if (count > 0) {
            throw exception(DEVICE_LEDGER_CODE_NOT_ONLY);
        }


        // 2. 验证父级设备类型是否存在且不能是自己的子节点
        validateParentDeviceType(Long.valueOf(updateReqVO.getParentId()));
        if (updateReqVO.getParentId() != null) {
            validateNotChildOfSelf(updateReqVO.getId(), Long.valueOf(updateReqVO.getParentId()));
        }

        // 3. 获取旧数据
        DeviceTypeDO oldDeviceType = getDeviceType(updateReqVO.getId());

        // 4. 更新
        DeviceTypeDO updateObj = BeanUtils.toBean(updateReqVO, DeviceTypeDO.class);

        // 5. 如果父级有变化，更新父级链
        if (!Objects.equals(oldDeviceType.getParentId(), updateReqVO.getParentId())) {
            if (updateReqVO.getParentId() != null && updateReqVO.getParentId() > 0) {
                DeviceTypeDO parent = getDeviceType(Long.valueOf(updateReqVO.getParentId()));
                updateObj.setParentChain(buildParentChain(parent));
            } else {
                updateObj.setParentChain(""); // 根节点
            }

            // 更新所有子节点的父级链
            updateChildrenParentChain(updateObj);
        }

        deviceTypeMapper.updateById(updateObj);
    }

    @Override
    public void deleteDeviceType(Long id) {
        // 1. 校验存在
        DeviceTypeDO deviceTypeDO = deviceTypeMapper.selectById(id);
        validateDeviceTypeExists(deviceTypeDO);

        // 2. 校验是否有子节点
        if (hasChildren(id)) {
            throw exception(DEVICE_TYPE_EXITS_CHILDREN);
        }
        // 3. 校验是否有引用
        validateReferences(deviceTypeDO);

        // 4. 删除
        deviceTypeMapper.deleteById(id);
    }

    private void validateReferences(DeviceTypeDO deviceTypeDO) {

        boolean isExists = deviceLedgerMapper.exists(Wrappers.<DeviceLedgerDO>lambdaQuery().eq(DeviceLedgerDO::getDeviceType,deviceTypeDO.getId()));
        if (isExists){
            throw exception(DEVICE_TYPE_REFERENCES);

        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void deleteDeviceTypeBatch(List<Long> ids) {
        for (Long id : ids) {
            deleteDeviceType(id);
        }
    }

    private void validateDeviceTypeExists(DeviceTypeDO deviceTypeDO) {
        if (deviceTypeDO == null) {
            throw exception(DEVICE_TYPE_NOT_EXISTS);
        }
    }

    @Override
    public DeviceTypeDO getDeviceType(Long id) {
        return deviceTypeMapper.selectById(id);
    }

    @Override
    public PageResult<DeviceTypeDO> getDeviceTypePage(DeviceTypePageReqVO pageReqVO) {
        return deviceTypeMapper.selectPage(pageReqVO);
    }

    @Override
    public List<DeviceTypeDO> getDeviceTypeList(DeviceTypeListReqVO listReqVO) {
        return deviceTypeMapper.selectList(listReqVO);
    }

    @Override
    public List<DeviceTypeTreeRespVO> getDeviceTypeTree(DeviceTypeListReqVO pageReqVO) {
        // 1. 查询所有设备类型
        List<DeviceTypeDO> allDeviceTypes = deviceTypeMapper.selectList(pageReqVO);

        // 2. 构建树形结构
        return buildDeviceTypeTree(allDeviceTypes);
    }

    @Override
    public List<DeviceTypeDO> getChildrenDeviceTypes(Long parentId) {
        LambdaQueryWrapper<DeviceTypeDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceTypeDO::getParentId, parentId)
                .orderByAsc(DeviceTypeDO::getSort, DeviceTypeDO::getId);
        return deviceTypeMapper.selectList(queryWrapper);
    }

    @Override
    public List<DeviceTypeDO> getAncestorDeviceTypes(Long id) {
        DeviceTypeDO deviceType = getDeviceType(id);
        if (deviceType == null || deviceType.getParentChain() == null ||
                deviceType.getParentChain().isEmpty()) {
            return Collections.emptyList();
        }

        String[] parentIds = deviceType.getParentChain().split(",");
        List<Long> ids = Arrays.stream(parentIds)
                .filter(s -> !s.isEmpty())
                .map(Long::valueOf)
                .collect(Collectors.toList());

        if (ids.isEmpty()) {
            return Collections.emptyList();
        }

        return deviceTypeMapper.selectBatchIds(ids);
    }

    // ========== 私有方法 ==========

    /**
     * 构建树形结构
     */
    private List<DeviceTypeTreeRespVO> buildDeviceTypeTree(List<DeviceTypeDO> allDeviceTypes) {
        // 按父级ID分组
        Map<Long, List<DeviceTypeDO>> childrenMap = CollectionUtils.convertMultiMap(
                allDeviceTypes, DeviceTypeDO::getParentId);

        // 创建ID到名称的映射
        Map<Long, String> parentNameMap = allDeviceTypes.stream()
                .collect(Collectors.toMap(
                        DeviceTypeDO::getId,
                        DeviceTypeDO::getName,
                        (v1, v2) -> v1
                ));

        // 获取根节点（parentId为空或0）
        List<DeviceTypeDO> rootDeviceTypes = childrenMap.getOrDefault(0L, Collections.emptyList());
        rootDeviceTypes.addAll(childrenMap.getOrDefault(null, Collections.emptyList()));

        // 排序
        rootDeviceTypes.sort(Comparator.comparing(DeviceTypeDO::getSort)
                .thenComparing(DeviceTypeDO::getId));

        // 递归构建树
        return rootDeviceTypes.stream()
                .map(deviceType -> convertToTree(deviceType, childrenMap,parentNameMap))
                .collect(Collectors.toList());
    }

    /**
     * 转换为树形节点
     */
    private DeviceTypeTreeRespVO convertToTree(DeviceTypeDO deviceType,
                                               Map<Long, List<DeviceTypeDO>> childrenMap,Map<Long, String> parentNameMap) {
        DeviceTypeTreeRespVO treeNode = BeanUtils.toBean(deviceType, DeviceTypeTreeRespVO.class);

        // 设置父类名称
        if (deviceType.getParentId() != null && deviceType.getParentId() > 0) {
            treeNode.setParentName(parentNameMap.getOrDefault(deviceType.getParentId(), ""));
        } else {
            treeNode.setParentName("顶级分类");
        }



        // 获取子节点
        List<DeviceTypeDO> children = childrenMap.getOrDefault(deviceType.getId(), Collections.emptyList());

        if (!children.isEmpty()) {
            // 排序
            children.sort(Comparator.comparing(DeviceTypeDO::getSort)
                    .thenComparing(DeviceTypeDO::getId));

            // 递归转换子节点
            List<DeviceTypeTreeRespVO> childNodes = children.stream()
                    .map(child -> convertToTree(child, childrenMap,parentNameMap))
                    .collect(Collectors.toList());

            treeNode.setChildren(childNodes);
            treeNode.setLeaf(false);
        }

        return treeNode;
    }

    /**
     * 验证父级设备类型是否存在
     */
    private void validateParentDeviceType(Long parentId) {
        if (parentId != null && parentId > 0) {
            if (deviceTypeMapper.selectById(parentId) == null) {
                throw exception(DEVICE_TYPE_PARENT_NOT_EXISTS);
            }
        }
    }

    /**
     * 验证不能设置自己或自己的子节点为父级
     */
    private void validateNotChildOfSelf(Long id, Long parentId) {
        if (id.equals(parentId)) {
            throw exception(DEVICE_TYPE_PARENT_IS_SELF);
        }

        // 获取父级的父级链
        DeviceTypeDO parent = getDeviceType(parentId);
        if (parent != null && parent.getParentChain() != null) {
            String parentChain = parent.getParentChain();
            if (parentChain.contains("," + id + ",") ||
                    parentChain.startsWith(id + ",") ||
                    parentChain.endsWith("," + id)) {
                throw exception(DEVICE_TYPE_PARENT_IS_CHILD);
            }
        }
    }

    /**
     * 检查是否有子节点
     */
    private boolean hasChildren(Long id) {
        LambdaQueryWrapper<DeviceTypeDO> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(DeviceTypeDO::getParentId, id);
        return deviceTypeMapper.selectCount(queryWrapper) > 0;
    }

    /**
     * 构建父级链
     */
    private String buildParentChain(DeviceTypeDO parent) {
        if (parent == null) {
            return "";
        }

        StringBuilder chain = new StringBuilder();
        if (parent.getParentChain() != null && !parent.getParentChain().isEmpty()) {
            chain.append(parent.getParentChain()).append(",");
        }
        chain.append(parent.getId());
        return chain.toString();
    }

    /**
     * 更新子节点的父级链
     */
    private void updateChildrenParentChain(DeviceTypeDO deviceType) {
        List<DeviceTypeDO> children = getChildrenDeviceTypes(deviceType.getId());
        for (DeviceTypeDO child : children) {
            String newParentChain = buildParentChain(deviceType);
            child.setParentChain(newParentChain);
            deviceTypeMapper.updateById(child);

            // 递归更新孙子节点
            updateChildrenParentChain(child);
        }
    }
}