package org.dromara.work.service.impl;

import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.StringUtils;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.mybatis.core.page.PageQuery;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.RequiredArgsConstructor;
import org.dromara.common.sse.dto.SseMessageDto;
import org.dromara.common.sse.utils.SseMessageUtils;
import org.dromara.system.domain.vo.SysUserVo;
import org.dromara.system.mapper.SysUserMapper;
import org.dromara.work.domain.TpComments;
import org.springframework.stereotype.Service;
import org.dromara.work.domain.bo.TpMessageBo;
import org.dromara.work.domain.vo.TpMessageVo;
import org.dromara.work.domain.TpMessage;
import org.dromara.work.mapper.TpMessageMapper;
import org.dromara.work.service.ITpMessageService;

import java.util.List;
import java.util.Map;
import java.util.Collection;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 消息Service业务层处理
 *
 * @author Maosw
 * @date 2025-04-18
 */
@RequiredArgsConstructor
@Service
public class TpMessageServiceImpl implements ITpMessageService {

    private final TpMessageMapper baseMapper;

    private final SysUserMapper userMapper;

    private final ScheduledExecutorService scheduledExecutorService;

    /**
     * 查询消息
     *
     * @param id 主键
     * @return 消息
     */
    @Override
    public TpMessageVo queryById(Long id){
        //设置消息已读
        baseMapper.update(null,new LambdaUpdateWrapper<TpMessage>().set(TpMessage::getStatus, 2).eq(TpMessage::getId, id));
        return baseMapper.selectVoById(id);
    }

    /**
     * 分页查询消息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 消息分页列表
     */
    @Override
    public TableDataInfo<TpMessageVo> queryPageList(TpMessageBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TpMessage> lqw = buildQueryWrapper(bo);
        Page<TpMessageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 分页查询消息列表
     *
     * @param bo        查询条件
     * @param pageQuery 分页参数
     * @return 消息分页列表
     */
    @Override
    public IPage<TpMessageVo> selectPageList(TpMessageBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<TpMessage> lqw = buildQueryWrapper(bo);
        Page<TpMessageVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        //循环赋值用户对象
        for (TpMessageVo messageVo : result.getRecords()) {
            SysUserVo sysUser = userMapper.selectVoById(messageVo.getUserId());
            messageVo.setUser(sysUser);
            if(messageVo.getToUserId() != null){
                SysUserVo sysUser1 = userMapper.selectVoById(messageVo.getToUserId());
                messageVo.setToUser(sysUser1);
            }
        }
        return result;
    }

    /**
     * 查询消息数量
     *
     * @return 消息数量
     */
    @Override
    public Long count(TpMessageBo bo) {
        return baseMapper.selectCount(new LambdaQueryWrapper<TpMessage>().eq(TpMessage::getToUserId, bo.getToUserId()).eq(bo.getType() != null,TpMessage::getType, bo.getType()).eq(TpMessage::getStatus, 1));
    }

    /**
     * 查询符合条件的消息列表
     *
     * @param bo 查询条件
     * @return 消息列表
     */
    @Override
    public List<TpMessageVo> queryList(TpMessageBo bo) {
        LambdaQueryWrapper<TpMessage> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<TpMessage> buildQueryWrapper(TpMessageBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<TpMessage> lqw = Wrappers.lambdaQuery();
        lqw.orderByAsc(TpMessage::getId);
        lqw.eq(bo.getUserId() != null, TpMessage::getUserId, bo.getUserId());
        lqw.eq(bo.getToUserId() != null, TpMessage::getToUserId, bo.getToUserId());
        lqw.eq(bo.getOrderId() != null, TpMessage::getOrderId, bo.getOrderId());
        lqw.eq(StringUtils.isNotBlank(bo.getOrderNum()), TpMessage::getOrderNum, bo.getOrderNum());
        lqw.eq(bo.getPictureId() != null, TpMessage::getPictureId, bo.getPictureId());
        lqw.eq(bo.getType() != null, TpMessage::getType, bo.getType());
        lqw.eq(bo.getStatus() != null, TpMessage::getStatus, bo.getStatus());
        lqw.between(params.get("beginCreateTime") != null && params.get("endCreateTime") != null,
            TpMessage::getCreateTime ,params.get("beginCreateTime"), params.get("endCreateTime"));
        return lqw;
    }

    /**
     * 新增消息
     *
     * @param bo 消息
     * @return 是否新增成功
     */
    @Override
    public Boolean insertByBo(TpMessageBo bo) {
        TpMessage add = MapstructUtils.convert(bo, TpMessage.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setId(add.getId());
            scheduledExecutorService.schedule(() -> {
                SseMessageDto dto = new SseMessageDto();
                dto.setMessage(add.getContent());
                dto.setUserIds(List.of(add.getToUserId()));
                dto.setMessageId(add.getId());
                SseMessageUtils.publishMessage(dto);
            }, 5, TimeUnit.SECONDS);
        }
        return flag;
    }

    /**
     * 修改消息
     *
     * @param bo 消息
     * @return 是否修改成功
     */
    @Override
    public Boolean updateByBo(TpMessageBo bo) {
        TpMessage update = MapstructUtils.convert(bo, TpMessage.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(TpMessage entity){
        //TODO 做一些数据校验,如唯一约束
    }

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