/**
 * 聊天记录查询模块
 * 提供通用的消息查询功能：搜索、筛选、上下文、无限滚动等
 * 在 Worker 线程中执行
 */

import { openDatabase, buildTimeFilter, type TimeFilter } from '../core'
import { ensureAvatarColumn } from './basic'
import { hasFtsIndex } from './fts'
import { tokenizeQueryForFts } from '../../nlp/ftsTokenizer'

// ==================== 类型定义 ====================

/**
 * 消息查询结果类型
 */
export interface MessageResult {
  id: number
  senderId: number
  senderName: string
  senderPlatformId: string
  senderAliases: string[]
  senderAvatar: string | null
  content: string
  timestamp: number
  type: number
  replyToMessageId: string | null
  replyToContent: string | null
  replyToSenderName: string | null
}

/**
 * 分页消息结果
 */
export interface PaginatedMessages {
  messages: MessageResult[]
  hasMore: boolean
}

/**
 * 带总数的消息结果
 */
export interface MessagesWithTotal {
  messages: MessageResult[]
  total: number
}

// ==================== 工具函数 ====================

/**
 * 数据库行类型（包含 aliases JSON 字符串和头像）
 */
interface DbMessageRow {
  id: number
  senderId: number
  senderName: string
  senderPlatformId: string
  aliases: string | null
  avatar: string | null
  content: string
  timestamp: number
  type: number
  reply_to_message_id: string | null
  replyToContent: string | null
  replyToSenderName: string | null
}

/**
 * 将数据库行转换为可序列化的 MessageResult
 * 处理 BigInt 等类型，确保 IPC 传输安全
 */
function sanitizeMessageRow(row: DbMessageRow): MessageResult {
  // 解析别名 JSON
  let aliases: string[] = []
  if (row.aliases) {
    try {
      aliases = JSON.parse(row.aliases)
    } catch {
      aliases = []
    }
  }

  return {
    id: Number(row.id),
    senderId: Number(row.senderId),
    senderName: String(row.senderName || ''),
    senderPlatformId: String(row.senderPlatformId || ''),
    senderAliases: aliases,
    senderAvatar: row.avatar || null,
    content: row.content != null ? String(row.content) : '',
    timestamp: Number(row.timestamp),
    type: Number(row.type),
    replyToMessageId: row.reply_to_message_id || null,
    replyToContent: row.replyToContent || null,
    replyToSenderName: row.replyToSenderName || null,
  }
}

/**
 * 构建通用的发送者筛选条件
 */
function buildSenderCondition(senderId?: number): { condition: string; params: number[] } {
  if (senderId === undefined) {
    return { condition: '', params: [] }
  }
  return { condition: 'AND msg.sender_id = ?', params: [senderId] }
}

/**
 * 构建关键词筛选条件（OR 逻辑）
 */
function buildKeywordCondition(keywords?: string[]): { condition: string; params: string[] } {
  if (!keywords || keywords.length === 0) {
    return { condition: '', params: [] }
  }
  const condition = `AND (${keywords.map(() => `msg.content LIKE ?`).join(' OR ')})`
  const params = keywords.map((k) => `%${k}%`)
  return { condition, params }
}

// 排除系统消息的通用过滤条件
const SYSTEM_FILTER = "AND COALESCE(m.account_name, '') != '系统消息'"

// 只获取文本消息的过滤条件
const TEXT_ONLY_FILTER = "AND msg.type = 0 AND msg.content IS NOT NULL AND msg.content != ''"

// ==================== 查询函数 ====================

/**
 * 获取最近的消息（AI Agent 专用，只返回文本消息）
 * @param sessionId 会话 ID
 * @param filter 时间过滤器
 * @param limit 返回数量限制
 */
export function getRecentMessages(sessionId: string, filter?: TimeFilter, limit: number = 100): MessagesWithTotal {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], total: 0 }

  // 构建时间过滤条件（使用 'msg' 表别名避免多表 JOIN 时的列名歧义）
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''

  // 查询总数
  const countSql = `
    SELECT COUNT(*) as total
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    WHERE 1=1
    ${timeCondition}
    ${SYSTEM_FILTER}
    ${TEXT_ONLY_FILTER}
  `
  const totalRow = db.prepare(countSql).get(...timeParams) as { total: number }
  const total = totalRow?.total || 0

  // 查询最近消息（按时间降序）
  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE 1=1
    ${timeCondition}
    ${SYSTEM_FILTER}
    ${TEXT_ONLY_FILTER}
    ORDER BY msg.ts DESC
    LIMIT ?
  `

  const rows = db.prepare(sql).all(...timeParams, limit) as DbMessageRow[]

  // 返回时按时间正序排列（便于阅读）
  return {
    messages: rows.map(sanitizeMessageRow).reverse(),
    total,
  }
}

/**
 * 获取所有最近的消息（消息查看器专用，包含所有类型消息）
 * @param sessionId 会话 ID
 * @param filter 时间过滤器
 * @param limit 返回数量限制
 */
export function getAllRecentMessages(sessionId: string, filter?: TimeFilter, limit: number = 100): MessagesWithTotal {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], total: 0 }

  // 构建时间过滤条件（使用 'msg' 表别名避免多表 JOIN 时的列名歧义）
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''

  // 查询总数
  const countSql = `
    SELECT COUNT(*) as total
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    WHERE 1=1
    ${timeCondition}
  `
  const totalRow = db.prepare(countSql).get(...timeParams) as { total: number }
  const total = totalRow?.total || 0

  // 查询最近消息（按时间降序）
  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE 1=1
    ${timeCondition}
    ORDER BY msg.ts DESC
    LIMIT ?
  `

  const rows = db.prepare(sql).all(...timeParams, limit) as DbMessageRow[]

  // 返回时按时间正序排列（便于阅读）
  return {
    messages: rows.map(sanitizeMessageRow).reverse(),
    total,
  }
}

/**
 * 关键词搜索消息
 * @param sessionId 会话 ID
 * @param keywords 关键词数组（OR 逻辑），可以为空数组
 * @param filter 时间过滤器
 * @param limit 返回数量限制
 * @param offset 偏移量（分页）
 * @param senderId 可选的发送者成员 ID
 */
export function searchMessages(
  sessionId: string,
  keywords: string[],
  filter?: TimeFilter,
  limit: number = 20,
  offset: number = 0,
  senderId?: number
): MessagesWithTotal {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], total: 0 }

  const useFts = keywords.length > 0 && hasFtsIndex(sessionId)
  let matchQuery = ''
  if (useFts) {
    matchQuery = tokenizeQueryForFts(keywords)
  }

  // FTS5 路径：使用倒排索引加速搜索
  if (useFts && matchQuery) {
    return searchMessagesWithFts(db, sessionId, matchQuery, filter, limit, offset, senderId)
  }

  // LIKE 路径（fallback）：旧数据库无 FTS 索引或无关键词
  return searchMessagesWithLike(db, keywords, filter, limit, offset, senderId)
}

/**
 * FTS5 搜索路径
 */
function searchMessagesWithFts(
  db: ReturnType<typeof openDatabase> & object,
  _sessionId: string,
  matchQuery: string,
  filter?: TimeFilter,
  limit: number = 20,
  offset: number = 0,
  senderId?: number
): MessagesWithTotal {
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''
  const { condition: senderCondition, params: senderParams } = buildSenderCondition(senderId)

  try {
    const countSql = `
      SELECT COUNT(*) as total
      FROM message msg
      JOIN member m ON msg.sender_id = m.id
      WHERE msg.id IN (SELECT rowid FROM message_fts WHERE content MATCH ?)
      ${timeCondition}
      ${senderCondition}
    `
    const totalRow = db.prepare(countSql).get(matchQuery, ...timeParams, ...senderParams) as { total: number }
    const total = totalRow?.total || 0

    const sql = `
      SELECT
        msg.id,
        m.id as senderId,
        COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
        m.platform_id as senderPlatformId,
        m.aliases,
        m.avatar,
        msg.content,
        msg.ts as timestamp,
        msg.type,
        msg.reply_to_message_id,
        reply_msg.content as replyToContent,
        COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
      FROM message msg
      JOIN member m ON msg.sender_id = m.id
      LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
      LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
      WHERE msg.id IN (SELECT rowid FROM message_fts WHERE content MATCH ?)
      ${timeCondition}
      ${senderCondition}
      ORDER BY msg.ts DESC
      LIMIT ? OFFSET ?
    `

    const rows = db.prepare(sql).all(matchQuery, ...timeParams, ...senderParams, limit, offset) as DbMessageRow[]

    return {
      messages: rows.map(sanitizeMessageRow),
      total,
    }
  } catch (error) {
    console.error('[FTS] searchMessages FTS path failed, falling back to LIKE:', error)
    return searchMessagesWithLike(db, [], filter, limit, offset, senderId)
  }
}

/**
 * LIKE 搜索路径（fallback 或 deep_search 使用）
 */
export function searchMessagesWithLike(
  db: ReturnType<typeof openDatabase> & object,
  keywords: string[],
  filter?: TimeFilter,
  limit: number = 20,
  offset: number = 0,
  senderId?: number
): MessagesWithTotal {
  let keywordCondition = '1=1'
  const keywordParams: string[] = []
  if (keywords.length > 0) {
    keywordCondition = `(${keywords.map(() => `msg.content LIKE ?`).join(' OR ')})`
    keywordParams.push(...keywords.map((k) => `%${k}%`))
  }

  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''
  const { condition: senderCondition, params: senderParams } = buildSenderCondition(senderId)

  const countSql = `
    SELECT COUNT(*) as total
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    WHERE ${keywordCondition}
    ${timeCondition}
    ${senderCondition}
  `
  const totalRow = db.prepare(countSql).get(...keywordParams, ...timeParams, ...senderParams) as { total: number }
  const total = totalRow?.total || 0

  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE ${keywordCondition}
    ${timeCondition}
    ${senderCondition}
    ORDER BY msg.ts DESC
    LIMIT ? OFFSET ?
  `

  const rows = db.prepare(sql).all(...keywordParams, ...timeParams, ...senderParams, limit, offset) as DbMessageRow[]

  return {
    messages: rows.map(sanitizeMessageRow),
    total,
  }
}

/**
 * 深度搜索消息（LIKE 子串匹配，速度较慢但不会遗漏）
 * 始终使用 LIKE 路径，不经过 FTS5。
 */
export function deepSearchMessages(
  sessionId: string,
  keywords: string[],
  filter?: TimeFilter,
  limit: number = 20,
  offset: number = 0,
  senderId?: number
): MessagesWithTotal {
  ensureAvatarColumn(sessionId)
  const db = openDatabase(sessionId)
  if (!db) return { messages: [], total: 0 }
  return searchMessagesWithLike(db, keywords, filter, limit, offset, senderId)
}

/**
 * 获取消息上下文（指定消息前后的消息）
 * 使用消息 ID 方式获取精确的前后 N 条消息
 *
 * @param sessionId 会话 ID
 * @param messageIds 消息 ID 列表（支持单个或批量）
 * @param contextSize 上下文大小，前后各多少条消息，默认 20
 */
export function getMessageContext(
  sessionId: string,
  messageIds: number | number[],
  contextSize: number = 20
): MessageResult[] {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return []

  // 统一转为数组
  const ids = Array.isArray(messageIds) ? messageIds : [messageIds]
  if (ids.length === 0) return []

  // 收集所有上下文消息的 ID（使用 Set 去重）
  const contextIds = new Set<number>()

  for (const messageId of ids) {
    // 添加目标消息本身
    contextIds.add(messageId)

    // 获取前 contextSize 条消息（id < messageId，按 id 降序取前 N 个）
    const beforeSql = `
      SELECT id FROM message
      WHERE id < ?
      ORDER BY id DESC
      LIMIT ?
    `
    const beforeRows = db.prepare(beforeSql).all(messageId, contextSize) as { id: number }[]
    beforeRows.forEach((row) => contextIds.add(row.id))

    // 获取后 contextSize 条消息（id > messageId，按 id 升序取前 N 个）
    const afterSql = `
      SELECT id FROM message
      WHERE id > ?
      ORDER BY id ASC
      LIMIT ?
    `
    const afterRows = db.prepare(afterSql).all(messageId, contextSize) as { id: number }[]
    afterRows.forEach((row) => contextIds.add(row.id))
  }

  // 如果没有找到任何消息
  if (contextIds.size === 0) return []

  // 批量查询所有上下文消息
  const idList = Array.from(contextIds)
  const placeholders = idList.map(() => '?').join(', ')

  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE msg.id IN (${placeholders})
    ORDER BY msg.id ASC
  `

  const rows = db.prepare(sql).all(...idList) as DbMessageRow[]

  return rows.map(sanitizeMessageRow)
}

/**
 * 获取搜索结果的上下文消息（会话感知 + 区间合并去重）
 * 用于 search_messages / deep_search_messages 自动扩展上下文。
 * 当存在会话索引时，上下文不跨会话边界；否则按 message.id 顺序取前后 N 条。
 *
 * @param sessionId 数据库会话 ID
 * @param messageIds 搜索命中的消息 ID 列表
 * @param contextBefore 每条命中消息向前取多少条上下文
 * @param contextAfter 每条命中消息向后取多少条上下文
 */
export function getSearchMessageContext(
  sessionId: string,
  messageIds: number[],
  contextBefore: number = 2,
  contextAfter: number = 2
): MessageResult[] {
  ensureAvatarColumn(sessionId)
  const db = openDatabase(sessionId)
  if (!db) return []
  if (messageIds.length === 0) return []

  const contextIds = new Set<number>()

  const hasSessionData =
    (db.prepare('SELECT 1 FROM message_context LIMIT 1').get() as { 1: number } | undefined) !== undefined

  for (const messageId of messageIds) {
    contextIds.add(messageId)

    if (hasSessionData) {
      const sessionRow = db.prepare('SELECT session_id FROM message_context WHERE message_id = ?').get(messageId) as
        | { session_id: number }
        | undefined

      if (sessionRow) {
        if (contextBefore > 0) {
          const rows = db
            .prepare(
              `SELECT mc.message_id as id
               FROM message_context mc
               WHERE mc.session_id = ? AND mc.message_id < ?
               ORDER BY mc.message_id DESC
               LIMIT ?`
            )
            .all(sessionRow.session_id, messageId, contextBefore) as { id: number }[]
          rows.forEach((r) => contextIds.add(r.id))
        }
        if (contextAfter > 0) {
          const rows = db
            .prepare(
              `SELECT mc.message_id as id
               FROM message_context mc
               WHERE mc.session_id = ? AND mc.message_id > ?
               ORDER BY mc.message_id ASC
               LIMIT ?`
            )
            .all(sessionRow.session_id, messageId, contextAfter) as { id: number }[]
          rows.forEach((r) => contextIds.add(r.id))
        }
        continue
      }
    }

    // Fallback: no session data or message not indexed — use simple id-based context
    if (contextBefore > 0) {
      const rows = db
        .prepare('SELECT id FROM message WHERE id < ? ORDER BY id DESC LIMIT ?')
        .all(messageId, contextBefore) as { id: number }[]
      rows.forEach((r) => contextIds.add(r.id))
    }
    if (contextAfter > 0) {
      const rows = db
        .prepare('SELECT id FROM message WHERE id > ? ORDER BY id ASC LIMIT ?')
        .all(messageId, contextAfter) as { id: number }[]
      rows.forEach((r) => contextIds.add(r.id))
    }
  }

  if (contextIds.size === 0) return []

  const idList = Array.from(contextIds)
  const placeholders = idList.map(() => '?').join(', ')

  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE msg.id IN (${placeholders})
    ORDER BY msg.ts ASC, msg.id ASC
  `

  const rows = db.prepare(sql).all(...idList) as DbMessageRow[]
  return rows.map(sanitizeMessageRow)
}

/**
 * 获取指定消息之前的 N 条消息（用于向上无限滚动）
 * @param sessionId 会话 ID
 * @param beforeId 在此消息 ID 之前的消息
 * @param limit 返回数量限制
 * @param filter 可选的时间筛选条件
 * @param senderId 可选的发送者筛选
 * @param keywords 可选的关键词筛选
 */
export function getMessagesBefore(
  sessionId: string,
  beforeId: number,
  limit: number = 50,
  filter?: TimeFilter,
  senderId?: number,
  keywords?: string[]
): PaginatedMessages {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], hasMore: false }

  // 构建时间过滤条件（使用 'msg' 表别名避免多表 JOIN 时的列名歧义）
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''

  // 构建关键词条件
  const { condition: keywordCondition, params: keywordParams } = buildKeywordCondition(keywords)

  // 构建发送者筛选条件
  const { condition: senderCondition, params: senderParams } = buildSenderCondition(senderId)

  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE msg.id < ?
    ${timeCondition}
    ${keywordCondition}
    ${senderCondition}
    ORDER BY msg.id DESC
    LIMIT ?
  `

  const rows = db
    .prepare(sql)
    .all(beforeId, ...timeParams, ...keywordParams, ...senderParams, limit + 1) as DbMessageRow[]

  const hasMore = rows.length > limit
  const resultRows = hasMore ? rows.slice(0, limit) : rows

  // 返回时按 ID 升序排列
  return {
    messages: resultRows.map(sanitizeMessageRow).reverse(),
    hasMore,
  }
}

/**
 * 获取指定消息之后的 N 条消息（用于向下无限滚动）
 * @param sessionId 会话 ID
 * @param afterId 在此消息 ID 之后的消息
 * @param limit 返回数量限制
 * @param filter 可选的时间筛选条件
 * @param senderId 可选的发送者筛选
 * @param keywords 可选的关键词筛选
 */
export function getMessagesAfter(
  sessionId: string,
  afterId: number,
  limit: number = 50,
  filter?: TimeFilter,
  senderId?: number,
  keywords?: string[]
): PaginatedMessages {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], hasMore: false }

  // 构建时间过滤条件（使用 'msg' 表别名避免多表 JOIN 时的列名歧义）
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''

  // 构建关键词条件
  const { condition: keywordCondition, params: keywordParams } = buildKeywordCondition(keywords)

  // 构建发送者筛选条件
  const { condition: senderCondition, params: senderParams } = buildSenderCondition(senderId)

  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE msg.id > ?
    ${timeCondition}
    ${keywordCondition}
    ${senderCondition}
    ORDER BY msg.id ASC
    LIMIT ?
  `

  const rows = db
    .prepare(sql)
    .all(afterId, ...timeParams, ...keywordParams, ...senderParams, limit + 1) as DbMessageRow[]

  const hasMore = rows.length > limit
  const resultRows = hasMore ? rows.slice(0, limit) : rows

  return {
    messages: resultRows.map(sanitizeMessageRow),
    hasMore,
  }
}

/**
 * 获取两个成员之间的对话
 * 提取两人相邻发言形成的对话片段
 * @param sessionId 会话 ID
 * @param memberId1 成员1的 ID
 * @param memberId2 成员2的 ID
 * @param filter 时间过滤器
 * @param limit 返回消息数量限制
 */
export function getConversationBetween(
  sessionId: string,
  memberId1: number,
  memberId2: number,
  filter?: TimeFilter,
  limit: number = 100
): MessagesWithTotal & { member1Name: string; member2Name: string } {
  // 确保数据库有 avatar 字段（兼容旧数据库）
  ensureAvatarColumn(sessionId)

  const db = openDatabase(sessionId)
  if (!db) return { messages: [], total: 0, member1Name: '', member2Name: '' }

  // 获取成员名称
  const member1 = db
    .prepare(
      `
    SELECT COALESCE(group_nickname, account_name, platform_id) as name
    FROM member WHERE id = ?
  `
    )
    .get(memberId1) as { name: string } | undefined

  const member2 = db
    .prepare(
      `
    SELECT COALESCE(group_nickname, account_name, platform_id) as name
    FROM member WHERE id = ?
  `
    )
    .get(memberId2) as { name: string } | undefined

  if (!member1 || !member2) {
    return { messages: [], total: 0, member1Name: '', member2Name: '' }
  }

  // 构建时间过滤条件（使用 'msg' 表别名避免多表 JOIN 时的列名歧义）
  const { clause: timeClause, params: timeParams } = buildTimeFilter(filter, 'msg')
  const timeCondition = timeClause ? timeClause.replace('WHERE', 'AND') : ''

  // 查询两人之间的所有消息
  const countSql = `
    SELECT COUNT(*) as total
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    WHERE msg.sender_id IN (?, ?)
    ${timeCondition}
    AND msg.content IS NOT NULL AND msg.content != ''
  `
  const totalRow = db.prepare(countSql).get(memberId1, memberId2, ...timeParams) as { total: number }
  const total = totalRow?.total || 0

  // 查询消息
  const sql = `
    SELECT
      msg.id,
      m.id as senderId,
      COALESCE(m.group_nickname, m.account_name, m.platform_id) as senderName,
      m.platform_id as senderPlatformId,
      m.aliases,
      m.avatar,
      msg.content,
      msg.ts as timestamp,
      msg.type,
      msg.reply_to_message_id,
      reply_msg.content as replyToContent,
      COALESCE(reply_m.group_nickname, reply_m.account_name, reply_m.platform_id) as replyToSenderName
    FROM message msg
    JOIN member m ON msg.sender_id = m.id
    LEFT JOIN message reply_msg ON msg.reply_to_message_id = reply_msg.platform_message_id
    LEFT JOIN member reply_m ON reply_msg.sender_id = reply_m.id
    WHERE msg.sender_id IN (?, ?)
    ${timeCondition}
    AND msg.content IS NOT NULL AND msg.content != ''
    ORDER BY msg.ts DESC
    LIMIT ?
  `

  const rows = db.prepare(sql).all(memberId1, memberId2, ...timeParams, limit) as DbMessageRow[]

  // 返回时按时间正序排列（便于阅读对话）
  return {
    messages: rows.map(sanitizeMessageRow).reverse(),
    total,
    member1Name: member1.name,
    member2Name: member2.name,
  }
}
