import { prisma } from '../../infra/database/prisma'

export class MessageRepository {
  /**
   * Histórico paginado por cursor (timestamp).
   * Retorna `limit` mensagens anteriores ao cursor dado.
   * Se cursor não for fornecido, retorna as mais recentes.
   */
  async findByChatPaginated(chatId: string, opts: {
    limit?: number
    before?: string   // timestamp ISO — cursor de paginação
    after?: string    // timestamp ISO — buscar mensagens mais novas
  } = {}) {
    const { limit = 40, before, after } = opts

    const where: Record<string, unknown> = { chatId }

    if (before) where['timestamp'] = { lt: new Date(before) }
    if (after) where['timestamp'] = { gt: new Date(after) }

    // Initial load (sem cursor) e scroll-up (before): busca DESC e inverte
    // para retornar as mensagens mais recentes em ordem cronológica.
    // Scroll-down (after): busca ASC naturalmente.
    const needsReverse = !after

    const messages = await prisma.message.findMany({
      where,
      orderBy: { timestamp: needsReverse ? 'desc' : 'asc' },
      take: limit,
      include: {
        replyTo: {
          select: {
            id: true,
            messageId: true,
            body: true,
            fromMe: true,
            type: true,
            mediaUrl: true,
          },
        },
      },
    })

    // Inverte para ordem cronológica (mais antiga → mais recente)
    if (needsReverse) messages.reverse()

    const hasMore = messages.length === limit

    return { messages, hasMore }
  }

  async findById(id: string) {
    return prisma.message.findUnique({ where: { id } })
  }

  async search(tenantId: string, instanceId: string, query: string, limit = 20) {
    return prisma.message.findMany({
      where: {
        tenantId,
        instanceId,
        body: { contains: query, mode: 'insensitive' },
      },
      include: {
        chat: {
          select: {
            jid: true,
            contact: { select: { name: true, notify: true, avatarUrl: true } },
          },
        },
      },
      orderBy: { timestamp: 'desc' },
      take: limit,
    })
  }

  async updateStatus(messageId: string, instanceId: string, status: string) {
    return prisma.message.updateMany({
      where: { messageId, instanceId },
      data: { status: status as any },
    })
  }

  async countByChat(chatId: string): Promise<number> {
    return prisma.message.count({ where: { chatId } })
  }
}
