package com.fuyuanshen.equipment.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fuyuanshen.common.core.domain.R;
import com.fuyuanshen.common.core.utils.MapstructUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.fuyuanshen.common.mybatis.core.page.TableDataInfo;
import com.fuyuanshen.common.satoken.utils.LoginHelper;
import com.fuyuanshen.equipment.domain.Device;
import com.fuyuanshen.equipment.domain.DeviceTypeGrants;
import com.fuyuanshen.equipment.mapper.DeviceMapper;
import jakarta.validation.constraints.NotEmpty;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import com.fuyuanshen.equipment.domain.bo.DeviceGroupBo;
import com.fuyuanshen.equipment.domain.vo.DeviceGroupVo;
import com.fuyuanshen.equipment.domain.DeviceGroup;
import com.fuyuanshen.equipment.mapper.DeviceGroupMapper;
import com.fuyuanshen.equipment.service.IDeviceGroupService;

import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.stream.Collectors;

/**
 * 设备分组Service业务层处理
 *
 * @author Lion Li
 * @date 2025-08-08
 */
@Slf4j
@RequiredArgsConstructor
@Service
public class DeviceGroupServiceImpl implements IDeviceGroupService {

    private final DeviceGroupMapper baseMapper;
    private final DeviceMapper deviceMapper;


    /**
     * 查询设备分组
     *
     * @param id 主键
     * @return 设备分组
     */
    @Override
    public DeviceGroupVo queryById(Long id) {
        return baseMapper.selectVoById(id);
    }


    /**
     * 查询符合条件的设备分组列表
     *
     * @param bo 查询条件
     * @return 设备分组列表
     */
    @Override
    public List<DeviceGroupVo> queryList(DeviceGroupBo bo) {
        Page<Device> page = new Page<>(bo.getPageNum(), bo.getPageSize());
        // 1. 查询顶级分组（parent_id为null）
        IPage<DeviceGroup> rootGroups = baseMapper.selectRootGroups(bo, page);
        List<DeviceGroup> records = rootGroups.getRecords();

        // 2. 递归构建树形结构
        return records.stream()
                .map(this::buildGroupTree)
                .collect(Collectors.toList());
    }

    private DeviceGroupVo buildGroupTree(DeviceGroup group) {
        DeviceGroupVo vo = convertToVO(group);
        // 递归查询子分组
        List<DeviceGroup> children = baseMapper.selectByParentId(group.getId());
        vo.setChildren(children.stream()
                .map(this::buildGroupTree)
                .collect(Collectors.toList()));
        return vo;
    }

    private DeviceGroupVo convertToVO(DeviceGroup group) {
        DeviceGroupVo vo = new DeviceGroupVo();
        vo.setId(group.getId());
        vo.setGroupName(group.getGroupName());
        vo.setStatus(group.getStatus() == 1 ? "正常" : "禁用");
        vo.setParentId(group.getParentId());
        vo.setCreateTime(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(group.getCreateTime()));
        return vo;
    }

    private LambdaQueryWrapper<DeviceGroup> buildQueryWrapper(DeviceGroupBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<DeviceGroup> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(DeviceGroup::getId);
        lqw.like(StringUtils.isNotBlank(bo.getGroupName()), DeviceGroup::getGroupName, bo.getGroupName());
        lqw.eq(bo.getStatus() != null, DeviceGroup::getStatus, bo.getStatus());
        lqw.eq(bo.getParentId() != null, DeviceGroup::getParentId, bo.getParentId());
        lqw.eq(StringUtils.isNotBlank(bo.getFullPath()), DeviceGroup::getFullPath, bo.getFullPath());
        lqw.eq(bo.getIsDeleted() != null, DeviceGroup::getIsDeleted, bo.getIsDeleted());
        return lqw;
    }


    /**
     * 新增设备分组
     *
     * @param bo 设备分组
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(DeviceGroupBo bo) {

        // 验证分组名称唯一性
        QueryWrapper<DeviceGroup> queryWrapper = new QueryWrapper<DeviceGroup>().eq("group_name", bo.getGroupName());
        if (bo.getParentId() != null) {
            queryWrapper.eq("parent_id", bo.getParentId());
        } else {
            queryWrapper.isNull("parent_id");
        }
        DeviceGroup deviceGroup = baseMapper.selectOne(queryWrapper);

        if (deviceGroup != null) {
            throw new RuntimeException("分组名称已存在,请勿重复添加！！！");
        }

        if (bo.getParentId() != null) {
            // 验证父分组是否存在（如果提供了parentId）
            DeviceGroup pDeviceGroup = baseMapper.selectById(bo.getParentId());
            if (bo.getParentId() != null && pDeviceGroup == null) {
                throw new RuntimeException("父分组不存在！！！");
            }
        }

        DeviceGroup add = MapstructUtils.convert(bo, DeviceGroup.class);
        // validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
        }
        return flag;
    }


    /**
     * 修改设备分组
     *
     * @param bo 设备分组
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(DeviceGroupBo bo) {
        DeviceGroup update = MapstructUtils.convert(bo, DeviceGroup.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(DeviceGroup bo) {
        // TODO 做一些数据校验,如唯一约束
        // 验证分组名称唯一性
        QueryWrapper<DeviceGroup> queryWrapper = new QueryWrapper<DeviceGroup>().eq("group_name", bo.getGroupName());
        if (bo.getParentId() != null) {
            queryWrapper.eq("parent_id", bo.getParentId());
        } else {
            queryWrapper.isNull("parent_id");
        }
        DeviceGroup deviceGroup = baseMapper.selectOne(queryWrapper);

        if (deviceGroup != null && deviceGroup.getId() != bo.getId()) {
            throw new RuntimeException("分组名称已存在,请勿重复添加！！！");
        }

    }


    /**
     * 校验并批量删除设备分组信息
     *
     * @param ids     待删除的主键集合
     * @param isValid 是否进行有效性校验
     * @return 是否删除成功
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {
            // TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteByIds(ids) > 0;
    }


    /**
     * 绑定设备分组
     *
     * @param groupId  分组id
     * @param deviceId 设备id
     * @return 是否绑定成功
     */
    @Override
    public Boolean bindingDevice(Long groupId, Long[] deviceId) {

        if (deviceId != null && deviceId.length > 0) {
            // 创建更新条件
            UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("id", Arrays.asList(deviceId));
            updateWrapper.set("group_id", groupId);

            // 执行批量更新
            deviceMapper.update(updateWrapper);
        }

        return true;
    }


    /**
     * 解绑设备分组
     *
     * @param deviceId 设备id
     * @return 是否解绑成功
     */
    @Override
    public Boolean groupUnbind(Long[] deviceId) {

        if (deviceId != null && deviceId.length > 0) {
            // 创建更新条件
            UpdateWrapper<Device> updateWrapper = new UpdateWrapper<>();
            updateWrapper.in("id", Arrays.asList(deviceId));
            updateWrapper.set("group_id", null);

            // 执行批量更新
            deviceMapper.update(updateWrapper);
        }

        return true;
    }

}
