'use strict'

const { query, queryOne } = require('../database/postgres')

class GroupChat {
  /**
   * Listar grupos em que o colaborador participa (via team_members) com unread_count
   */
  static async listForAccount(tenantId, accountId) {
    return query(
      `SELECT gc.id, gc.sector_id, gc.name,
              s.icon, s.color,
              (SELECT gm.content
               FROM group_messages gm
               WHERE gm.group_chat_id = gc.id
               ORDER BY gm.created_at DESC LIMIT 1) AS last_message,
              (SELECT gm.created_at
               FROM group_messages gm
               WHERE gm.group_chat_id = gc.id
               ORDER BY gm.created_at DESC LIMIT 1) AS last_message_at,
              (SELECT COUNT(*)::int
               FROM group_messages gm2
               LEFT JOIN group_last_read glr
                 ON glr.group_chat_id = gm2.group_chat_id AND glr.account_id = $2
               WHERE gm2.group_chat_id = gc.id
                 AND gm2.from_account != $2
                 AND (glr.last_read_at IS NULL OR gm2.created_at > glr.last_read_at)
              ) AS unread_count
       FROM group_chats gc
       JOIN sectors s ON s.id = gc.sector_id
       JOIN team_members tm ON tm.sector_id = gc.sector_id AND tm.account_id = $2
       WHERE gc.tenant_id = $1
       ORDER BY s.sort_order, gc.name`,
      [tenantId, accountId]
    )
  }

  /**
   * Listar todos os grupos do tenant (para owners/managers) com unread_count
   */
  static async listAll(tenantId, accountId) {
    return query(
      `SELECT gc.id, gc.sector_id, gc.name,
              s.icon, s.color,
              (SELECT gm.content
               FROM group_messages gm
               WHERE gm.group_chat_id = gc.id
               ORDER BY gm.created_at DESC LIMIT 1) AS last_message,
              (SELECT gm.created_at
               FROM group_messages gm
               WHERE gm.group_chat_id = gc.id
               ORDER BY gm.created_at DESC LIMIT 1) AS last_message_at,
              (SELECT COUNT(*)::int
               FROM group_messages gm2
               LEFT JOIN group_last_read glr
                 ON glr.group_chat_id = gm2.group_chat_id AND glr.account_id = $2
               WHERE gm2.group_chat_id = gc.id
                 AND gm2.from_account != $2
                 AND (glr.last_read_at IS NULL OR gm2.created_at > glr.last_read_at)
              ) AS unread_count
       FROM group_chats gc
       JOIN sectors s ON s.id = gc.sector_id
       WHERE gc.tenant_id = $1
       ORDER BY s.sort_order, gc.name`,
      [tenantId, accountId]
    )
  }

  /**
   * Marcar grupo como lido (upsert last_read_at)
   */
  static async markRead(accountId, groupChatId) {
    await queryOne(
      `INSERT INTO group_last_read (account_id, group_chat_id, last_read_at)
       VALUES ($1, $2, NOW())
       ON CONFLICT (account_id, group_chat_id)
       DO UPDATE SET last_read_at = NOW()`,
      [accountId, groupChatId]
    )
  }

  /**
   * Buscar grupo por id, verificando pertença ao tenant
   */
  static async findById(tenantId, groupChatId) {
    return queryOne(
      `SELECT gc.*, s.name AS sector_name, s.icon, s.color,
              (SELECT COUNT(*)::int FROM team_members tm WHERE tm.sector_id = s.id) AS member_count
       FROM group_chats gc
       JOIN sectors s ON s.id = gc.sector_id
       WHERE gc.id = $1 AND gc.tenant_id = $2`,
      [groupChatId, tenantId]
    )
  }

  /**
   * Buscar mensagens de um grupo (paginação por cursor)
   */
  static async getMessages(tenantId, groupChatId, limit = 50, before = null) {
    const params = [tenantId, groupChatId, limit]
    const beforeClause = before ? `AND gm.created_at < $4` : ''
    if (before) params.push(before)

    const msgs = await query(
      `SELECT gm.id, gm.from_account, gm.content, gm.created_at,
              a.name AS sender_name, a.avatar_url AS sender_avatar
       FROM group_messages gm
       LEFT JOIN accounts a ON a.id = gm.from_account
       WHERE gm.tenant_id = $1
         AND gm.group_chat_id = $2
         ${beforeClause}
       ORDER BY gm.created_at DESC
       LIMIT $3`,
      params
    )
    return msgs.reverse()
  }

  /**
   * Enviar mensagem em um grupo
   */
  static async sendMessage(tenantId, groupChatId, fromAccount, content) {
    return queryOne(
      `INSERT INTO group_messages (tenant_id, group_chat_id, from_account, content)
       VALUES ($1, $2, $3, $4)
       RETURNING id, group_chat_id, from_account, content, created_at`,
      [tenantId, groupChatId, fromAccount, content]
    )
  }

  /**
   * Listar membros de um grupo (via team_members do setor)
   */
  static async getMembers(tenantId, groupChatId) {
    return query(
      `SELECT a.id, a.name, a.avatar_url, a.availability
       FROM group_chats gc
       JOIN team_members tm ON tm.sector_id = gc.sector_id
       JOIN accounts a ON a.id = tm.account_id
       WHERE gc.id = $1 AND gc.tenant_id = $2 AND a.active = TRUE
       ORDER BY a.name`,
      [groupChatId, tenantId]
    )
  }

  /**
   * IDs dos membros de um grupo (para SSE direcionado)
   */
  static async getMemberIds(groupChatId) {
    const rows = await query(
      `SELECT tm.account_id
       FROM group_chats gc
       JOIN team_members tm ON tm.sector_id = gc.sector_id
       WHERE gc.id = $1`,
      [groupChatId]
    )
    return rows.map(r => r.account_id)
  }
}

module.exports = GroupChat
