package cn.iocoder.yudao.module.server.service.materialinfo;

import cn.iocoder.yudao.module.server.dal.dataobject.materialshareuser.MaterialShareUserDO;
import cn.iocoder.yudao.module.server.dal.mysql.materialshareuser.MaterialShareUserMapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.mzt.logapi.starter.annotation.LogRecord;
import org.apache.commons.lang3.StringUtils;
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 cn.iocoder.yudao.module.server.controller.admin.materialinfo.vo.*;
import cn.iocoder.yudao.module.server.dal.dataobject.materialinfo.MaterialInfoDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.PageParam;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.server.dal.mysql.materialinfo.MaterialInfoMapper;

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

/**
 * 资料库 Service 实现类
 *
 * @author 超级管理员
 */
@Service
@Validated
public class MaterialInfoServiceImpl implements MaterialInfoService {

    @Resource
    private MaterialInfoMapper materialInfoMapper;

    @Resource
    private MaterialShareUserMapper materialShareUserMapper;

    @LogRecord(
            type = SYSTEM_MATERIAL_TYPE,
            subType = SYSTEM_MATERIAL_CREATE_SUB_TYPE,
            bizNo = "230",
            success = SYSTEM_MATERIAL_CREATE_SUCCESS
    )
    public Long createMaterialInfo(MaterialInfoSaveReqVO createReqVO) {
        // 插入
        MaterialInfoDO materialInfo = BeanUtils.toBean(createReqVO, MaterialInfoDO.class);
        materialInfoMapper.insert(materialInfo);
        // 返回
        return materialInfo.getId();
    }

    @LogRecord(
            type = SYSTEM_MATERIAL_TYPE,
            subType = SYSTEM_MATERIAL_UPDATE_SUB_TYPE,
            bizNo = "230",
            success = SYSTEM_MATERIAL_UPDATE_SUCCESS
    )
    public void updateMaterialInfo(MaterialInfoSaveReqVO updateReqVO) {
        // 校验存在
        validateMaterialInfoExists(updateReqVO.getId());
        // 更新
        MaterialInfoDO updateObj = BeanUtils.toBean(updateReqVO, MaterialInfoDO.class);
        materialInfoMapper.updateById(updateObj);
    }

    @LogRecord(
            type = SYSTEM_MATERIAL_TYPE,
            subType = SYSTEM_MATERIAL_DELETE_SUB_TYPE,
            bizNo = "230",
            success = SYSTEM_MATERIAL_DELETE_SUCCESS
    )
    public void deleteMaterialInfo(Long id) {
        // 校验存在
        validateMaterialInfoExists(id);
        // 删除
        materialInfoMapper.deleteById(id);
    }

    private void validateMaterialInfoExists(Long id) {
        if (materialInfoMapper.selectById(id) == null) {
            throw exception(MATERIAL_INFO_NOT_EXISTS);
        }
    }

    @Override
    public MaterialInfoDO getMaterialInfo(Long id) {
        return materialInfoMapper.selectById(id);
    }

    @Override
    public PageResult<MaterialInfoDO> getMaterialInfoPage(MaterialInfoPageReqVO pageReqVO) {
        return materialInfoMapper.selectPage(pageReqVO);
    }

    @Override
    public PageResult<MaterialInfoDO> getMaterialInfoPageByUser(MaterialInfoPageReqVO pageReqVO, Long userId) {
        // 1. 查询用户有权限查看的资料ID列表
        Set<Long> accessibleMaterialIds = getAccessibleMaterialIds(userId);

        // 2. 如果没有权限查看任何资料，返回空结果
        if (accessibleMaterialIds.isEmpty()) {
            return new PageResult<>(Collections.emptyList(), 0L);
        }

        // 3. 构建查询条件
        LambdaQueryWrapper<MaterialInfoDO> queryWrapper = new LambdaQueryWrapper<MaterialInfoDO>()
                .in(MaterialInfoDO::getId, accessibleMaterialIds)
                .like(StringUtils.isNotBlank(pageReqVO.getName()), MaterialInfoDO::getName, pageReqVO.getName())
                .eq(pageReqVO.getCategoryId() != null, MaterialInfoDO::getCategoryId, pageReqVO.getCategoryId())
                .like(StringUtils.isNotBlank(pageReqVO.getCategoryName()), MaterialInfoDO::getCategoryName, pageReqVO.getCategoryName())
                /*.eq(pageReqVO.getStatus() != null, MaterialInfoDO::getStatus, pageReqVO.getStatus())*/
                .orderByDesc(MaterialInfoDO::getCreateTime);

        // 4. 执行分页查询
        Page<MaterialInfoDO> page = new Page<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());
        IPage<MaterialInfoDO> pageResult = materialInfoMapper.selectPage(page, queryWrapper);

        return new PageResult<>(pageResult.getRecords(), pageResult.getTotal());
    }

    /**
     * 获取用户有权限查看的资料ID集合
     */
    private Set<Long> getAccessibleMaterialIds(Long userId) {
        Set<Long> materialIds = new HashSet<>();

        // 1. 添加共享类型为"全部用户"的资料
        List<MaterialInfoDO> publicMaterials = materialInfoMapper.selectList(
                new LambdaQueryWrapper<MaterialInfoDO>()
                        .eq(MaterialInfoDO::getShareType, 1) // 1表示全部用户
                        /*.eq(MaterialInfoDO::getStatus, 1)    // 只查询启用状态的*/
        );
        publicMaterials.forEach(m -> materialIds.add(m.getId()));

        // 2. 添加指定给该用户的资料
        List<MaterialShareUserDO> sharedMaterials = materialShareUserMapper.selectList(
                new LambdaQueryWrapper<MaterialShareUserDO>()
                        .eq(MaterialShareUserDO::getUserId, userId)
        );
        sharedMaterials.forEach(s -> materialIds.add(s.getMaterialId()));

        return materialIds;
    }



}