import { prisma } from '../../config/database';
import { rocketchatClient } from '../../services/rocketchat.client';
import { rocketchatService } from '../rocketchat/rocketchat.service';
import { friendshipService } from './friendship.service';
import { logger } from '../../utils/logger';

export const messagingService = {
  /**
   * Open or get an existing DM channel between two users.
   * Provisions both users in RC if needed, creates DM room, returns room info.
   */
  async openDM(userId: string, friendId: string) {
    // Validate: must be friends
    const friendIds = await friendshipService.getFriendIds(userId);
    if (!friendIds.includes(friendId)) {
      throw Object.assign(new Error('You can only message friends'), { statusCode: 403 });
    }

    // Check block
    const blocked = await friendshipService.isBlocked(userId, friendId);
    if (blocked) {
      throw Object.assign(new Error('Cannot message this user'), { statusCode: 403 });
    }

    // Check if RC is available
    const rcOnline = await rocketchatClient.healthCheck();
    if (!rcOnline) {
      throw Object.assign(new Error('Chat service is currently unavailable'), { statusCode: 503 });
    }

    // Provision both users in RC (gets/creates their RC accounts)
    let senderAuth, recipientAuth;
    try {
      [senderAuth, recipientAuth] = await Promise.all([
        rocketchatService.getAuthToken(userId),
        rocketchatService.getAuthToken(friendId),
      ]);
    } catch (err) {
      logger.error('Failed to provision RC users for DM:', err);
      throw Object.assign(new Error('Failed to set up chat accounts'), { statusCode: 500 });
    }

    // Look up RC usernames by RC user IDs
    const [senderUser, recipientUser] = await Promise.all([
      prisma.user.findUnique({ where: { id: userId }, select: { email: true, name: true } }),
      prisma.user.findUnique({ where: { id: friendId }, select: { email: true, name: true } }),
    ]);

    // Find the RC usernames from the RC user IDs
    const [senderRCUser, recipientRCUser] = await Promise.all([
      rocketchatClient.findUserByEmail(senderUser!.email),
      rocketchatClient.findUserByEmail(recipientUser!.email),
    ]);

    if (!senderRCUser || !recipientRCUser) {
      throw Object.assign(new Error('Chat accounts not fully provisioned'), { statusCode: 500 });
    }

    // Create or get DM room
    const dmRoom = await rocketchatClient.createDM([senderRCUser.username, recipientRCUser.username]);

    return {
      roomId: dmRoom.roomId,
      rcUsernames: dmRoom.usernames,
      friend: recipientUser ? {
        id: friendId,
        name: recipientUser.name,
        email: recipientUser.email,
      } : null,
    };
  },
};
