package com.red.circle.other.infra.database.mongo.service.message.impl;

import com.red.circle.other.infra.database.mongo.entity.message.UserMessage;
import java.sql.Timestamp;
import java.util.List;
import java.util.UUID;

import com.red.circle.other.infra.database.mongo.service.message.UserMessageService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import org.springframework.data.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

/**
 * 用户消息服务实现类.
 *
 * @author tf
 * @date 2025-10-14
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class UserMessageServiceImpl implements UserMessageService {

  private final MongoTemplate mongoTemplate;

  @Override
  public Page<UserMessage> pageUserMessages(Long userId, Boolean isRead, Integer pageNo,
      Integer pageSize) {
    log.info("分页查询用户消息, userId={}, isRead={}, pageNo={}, pageSize={}", 
        userId, isRead, pageNo, pageSize);

    // 构建查询条件
    Criteria criteria = Criteria.where("to_user_id").is(userId)
        .and("is_deleted").is(false);

    if (isRead != null) {
      criteria.and("is_read").is(isRead);
    }

    Query query = new Query(criteria);

    // 分页和排序
    Pageable pageable = PageRequest.of(pageNo - 1, pageSize, 
        Sort.by(Sort.Direction.DESC, "created_at"));
    query.with(pageable);

    // 查询数据
    List<UserMessage> messages = mongoTemplate.find(query, UserMessage.class);

    // 查询总数
    long total = mongoTemplate.count(Query.of(query).limit(-1).skip(-1), UserMessage.class);

    return PageableExecutionUtils.getPage(messages, pageable, () -> total);
  }

  @Override
  public Long countUnreadMessages(Long userId) {
    log.info("查询未读消息数量, userId={}", userId);

    Criteria criteria = Criteria.where("to_user_id").is(userId)
        .and("is_read").is(false)
        .and("is_deleted").is(false);

    Query query = new Query(criteria);

    return mongoTemplate.count(query, UserMessage.class);
  }

  @Override
  public UserMessage getByMessageId(String messageId) {
    log.info("根据消息ID查询, messageId={}", messageId);

    if (!StringUtils.hasText(messageId)) {
      return null;
    }

    Query query = new Query(Criteria.where("message_id").is(messageId));
    return mongoTemplate.findOne(query, UserMessage.class);
  }

  @Override
  public List<UserMessage> listByActionType(Long userId, String actionType, Integer limit) {
    log.info("根据动作类型查询消息列表, userId={}, actionType={}, limit={}", 
        userId, actionType, limit);

    Criteria criteria = Criteria.where("to_user_id").is(userId)
        .and("action_type").is(actionType)
        .and("is_deleted").is(false);

    Query query = new Query(criteria)
        .with(Sort.by(Sort.Direction.DESC, "created_at"))
        .limit(limit);

    return mongoTemplate.find(query, UserMessage.class);
  }

  @Override
  public UserMessage createUserMessage(UserMessage message) {
    log.info("创建用户消息, toUserId={}, fromType={}", 
        message.getToUserId(), message.getFromType());

    // 生成消息ID
    if (!StringUtils.hasText(message.getMessageId())) {
      message.setMessageId(generateMessageId());
    }

    // 设置默认值
    if (message.getIsRead() == null) {
      message.setIsRead(false);
    }
    if (message.getIsDeleted() == null) {
      message.setIsDeleted(false);
    }

    // 设置创建时间
    Timestamp now = new Timestamp(System.currentTimeMillis());
    message.setCreatedAt(now);

    // 保存到数据库
    return mongoTemplate.insert(message);
  }

  @Override
  public List<UserMessage> batchCreateUserMessages(List<UserMessage> messages) {
    log.info("批量创建用户消息, count={}", messages.size());

    if (CollectionUtils.isEmpty(messages)) {
      return messages;
    }

    Timestamp now = new Timestamp(System.currentTimeMillis());

    // 批量设置默认值
    messages.forEach(message -> {
      if (!StringUtils.hasText(message.getMessageId())) {
        message.setMessageId(generateMessageId());
      }
      if (message.getIsRead() == null) {
        message.setIsRead(false);
      }
      if (message.getIsDeleted() == null) {
        message.setIsDeleted(false);
      }
      message.setCreatedAt(now);
    });

    // 批量插入
    return (List<UserMessage>) mongoTemplate.insertAll(messages);
  }

  @Override
  public Boolean markAsRead(String messageId, Long userId) {
    log.info("标记消息已读, messageId={}, userId={}", messageId, userId);

    Criteria criteria = Criteria.where("message_id").is(messageId)
        .and("to_user_id").is(userId);

    Update update = new Update()
        .set("is_read", true)
        .set("read_at", new Timestamp(System.currentTimeMillis()));

    return mongoTemplate.updateFirst(new Query(criteria), update, UserMessage.class)
        .getModifiedCount() > 0;
  }

  @Override
  public Boolean batchMarkAsRead(List<String> messageIds, Long userId) {
    log.info("批量标记消息已读, userId={}, count={}", userId, messageIds.size());

    if (CollectionUtils.isEmpty(messageIds)) {
      return false;
    }

    Criteria criteria = Criteria.where("message_id").in(messageIds)
        .and("to_user_id").is(userId);

    Update update = new Update()
        .set("is_read", true)
        .set("read_at", new Timestamp(System.currentTimeMillis()));

    return mongoTemplate.updateMulti(new Query(criteria), update, UserMessage.class)
        .getModifiedCount() > 0;
  }

  @Override
  public Boolean markAllAsRead(Long userId) {
    log.info("标记所有消息已读, userId={}", userId);

    Criteria criteria = Criteria.where("to_user_id").is(userId)
        .and("is_read").is(false)
        .and("is_deleted").is(false);

    Update update = new Update()
        .set("is_read", true)
        .set("read_at", new Timestamp(System.currentTimeMillis()));

    return mongoTemplate.updateMulti(new Query(criteria), update, UserMessage.class)
        .getModifiedCount() > 0;
  }

  @Override
  public Boolean deleteMessage(String messageId, Long userId) {
    log.info("删除消息, messageId={}, userId={}", messageId, userId);

    Criteria criteria = Criteria.where("message_id").is(messageId)
        .and("to_user_id").is(userId);

    Update update = new Update().set("is_deleted", true);

    return mongoTemplate.updateFirst(new Query(criteria), update, UserMessage.class)
        .getModifiedCount() > 0;
  }

  @Override
  public Boolean batchDeleteMessages(List<String> messageIds, Long userId) {
    log.info("批量删除消息, userId={}, count={}", userId, messageIds.size());

    if (CollectionUtils.isEmpty(messageIds)) {
      return false;
    }

    Criteria criteria = Criteria.where("message_id").in(messageIds)
        .and("to_user_id").is(userId);

    Update update = new Update().set("is_deleted", true);

    return mongoTemplate.updateMulti(new Query(criteria), update, UserMessage.class)
        .getModifiedCount() > 0;
  }

  /**
   * 生成消息ID.
   *
   * @return 消息ID
   */
  private String generateMessageId() {
    return "msg_" + UUID.randomUUID().toString().replace("-", "");
  }

}