/**
 * In-Game Chat System
 * Real-time multiplayer chat for tournaments and social features
 */

export type ChatRoomType = 'tournament' | 'game' | 'global' | 'private' | 'team';
export type MessageType = 'text' | 'emoji' | 'system' | 'achievement' | 'trade';

export interface ChatMessage {
  id: string;
  roomId: string;
  userId: number;
  username: string;
  userAvatar?: string;
  messageType: MessageType;
  content: string;
  timestamp: Date;
  edited: boolean;
  editedAt?: Date;
  reactions: Record<string, number>;
  repliedToId?: string;
  attachments?: ChatAttachment[];
}

export interface ChatAttachment {
  type: 'image' | 'emoji' | 'achievement';
  url: string;
  description?: string;
}

export interface ChatRoom {
  id: string;
  name: string;
  type: ChatRoomType;
  description?: string;
  createdBy: number;
  createdAt: Date;
  members: number[];
  maxMembers?: number;
  isPrivate: boolean;
  messages: ChatMessage[];
  settings: ChatRoomSettings;
  moderation: ModerationSettings;
}

export interface ChatRoomSettings {
  allowImages: boolean;
  allowEmoji: boolean;
  allowLinks: boolean;
  messageRetentionDays: number;
  slowMode: boolean;
  slowModeInterval: number; // seconds
}

export interface ModerationSettings {
  profanityFilter: boolean;
  spamFilter: boolean;
  rateLimitPerMinute: number;
  bannedWords: string[];
  bannedUsers: number[];
  mutedUsers: number[];
}

export interface UserChatStatus {
  userId: number;
  username: string;
  status: 'online' | 'away' | 'offline';
  currentRoom?: string;
  lastSeen: Date;
  unreadMessages: number;
}

export interface ChatNotification {
  id: string;
  userId: number;
  type: 'mention' | 'reply' | 'achievement' | 'trade_request';
  fromUserId: number;
  fromUsername: string;
  roomId: string;
  messageId: string;
  content: string;
  read: boolean;
  createdAt: Date;
}

/**
 * Create chat room
 */
export function createChatRoom(
  name: string,
  type: ChatRoomType,
  createdBy: number,
  isPrivate: boolean = false,
  maxMembers?: number
): ChatRoom {
  return {
    id: `room_${type}_${Date.now()}`,
    name,
    type,
    createdBy,
    createdAt: new Date(),
    members: [createdBy],
    maxMembers,
    isPrivate,
    messages: [],
    settings: {
      allowImages: true,
      allowEmoji: true,
      allowLinks: false,
      messageRetentionDays: 30,
      slowMode: false,
      slowModeInterval: 0,
    },
    moderation: {
      profanityFilter: true,
      spamFilter: true,
      rateLimitPerMinute: 10,
      bannedWords: [],
      bannedUsers: [],
      mutedUsers: [],
    },
  };
}

/**
 * Add member to chat room
 */
export function addMemberToChatRoom(room: ChatRoom, userId: number): boolean {
  if (room.members.includes(userId)) {
    return false;
  }

  if (room.maxMembers && room.members.length >= room.maxMembers) {
    return false;
  }

  if (room.moderation.bannedUsers.includes(userId)) {
    return false;
  }

  room.members.push(userId);
  return true;
}

/**
 * Remove member from chat room
 */
export function removeMemberFromChatRoom(room: ChatRoom, userId: number): boolean {
  const index = room.members.indexOf(userId);
  if (index === -1) {
    return false;
  }

  room.members.splice(index, 1);
  return true;
}

/**
 * Create chat message
 */
export function createChatMessage(
  roomId: string,
  userId: number,
  username: string,
  content: string,
  messageType: MessageType = 'text',
  userAvatar?: string
): ChatMessage {
  return {
    id: `msg_${roomId}_${userId}_${Date.now()}`,
    roomId,
    userId,
    username,
    userAvatar,
    messageType,
    content,
    timestamp: new Date(),
    edited: false,
    reactions: {},
  };
}

/**
 * Add message to room
 */
export function addMessageToRoom(room: ChatRoom, message: ChatMessage): boolean {
  if (!room.members.includes(message.userId)) {
    return false;
  }

  if (room.moderation.mutedUsers.includes(message.userId)) {
    return false;
  }

  // Check message retention
  const retentionMs = room.settings.messageRetentionDays * 24 * 60 * 60 * 1000;
  room.messages = room.messages.filter((m) => Date.now() - m.timestamp.getTime() < retentionMs);

  room.messages.push(message);
  return true;
}

/**
 * Edit message
 */
export function editMessage(message: ChatMessage, newContent: string): void {
  message.content = newContent;
  message.edited = true;
  message.editedAt = new Date();
}

/**
 * Delete message
 */
export function deleteMessage(room: ChatRoom, messageId: string): boolean {
  const index = room.messages.findIndex((m) => m.id === messageId);
  if (index === -1) {
    return false;
  }

  room.messages.splice(index, 1);
  return true;
}

/**
 * Add reaction to message
 */
export function addReactionToMessage(message: ChatMessage, emoji: string): void {
  message.reactions[emoji] = (message.reactions[emoji] || 0) + 1;
}

/**
 * Remove reaction from message
 */
export function removeReactionFromMessage(message: ChatMessage, emoji: string): void {
  if (message.reactions[emoji]) {
    message.reactions[emoji]--;
    if (message.reactions[emoji] === 0) {
      delete message.reactions[emoji];
    }
  }
}

/**
 * Mute user in room
 */
export function muteUserInRoom(room: ChatRoom, userId: number, durationMinutes: number = 60): void {
  room.moderation.mutedUsers.push(userId);

  // Auto-unmute after duration
  setTimeout(() => {
    const index = room.moderation.mutedUsers.indexOf(userId);
    if (index !== -1) {
      room.moderation.mutedUsers.splice(index, 1);
    }
  }, durationMinutes * 60 * 1000);
}

/**
 * Ban user from room
 */
export function banUserFromRoom(room: ChatRoom, userId: number): void {
  room.moderation.bannedUsers.push(userId);
  removeMemberFromChatRoom(room, userId);
}

/**
 * Unban user from room
 */
export function unbanUserFromRoom(room: ChatRoom, userId: number): void {
  const index = room.moderation.bannedUsers.indexOf(userId);
  if (index !== -1) {
    room.moderation.bannedUsers.splice(index, 1);
  }
}

/**
 * Check if message contains profanity
 */
export function containsProfanity(message: ChatMessage, bannedWords: string[]): boolean {
  const lowerContent = message.content.toLowerCase();
  return bannedWords.some((word) => lowerContent.includes(word.toLowerCase()));
}

/**
 * Filter message content
 */
export function filterMessageContent(content: string, bannedWords: string[]): string {
  let filtered = content;
  bannedWords.forEach((word) => {
    const regex = new RegExp(word, 'gi');
    filtered = filtered.replace(regex, '*'.repeat(word.length));
  });
  return filtered;
}

/**
 * Get chat statistics
 */
export interface ChatStats {
  totalMessages: number;
  activeUsers: number;
  averageMessageLength: number;
  messagesPerMinute: number;
  topUsers: Array<{ userId: number; username: string; messageCount: number }>;
}

export function calculateChatStats(room: ChatRoom): ChatStats {
  const totalMessages = room.messages.length;
  const activeUsers = new Set(room.messages.map((m) => m.userId)).size;
  const averageMessageLength = totalMessages > 0
    ? room.messages.reduce((sum, m) => sum + m.content.length, 0) / totalMessages
    : 0;

  const now = Date.now();
  const messagesLastMinute = room.messages.filter((m) => now - m.timestamp.getTime() < 60000).length;

  const userMessageCounts: Record<number, { username: string; count: number }> = {};
  room.messages.forEach((m) => {
    if (!userMessageCounts[m.userId]) {
      userMessageCounts[m.userId] = { username: m.username, count: 0 };
    }
    userMessageCounts[m.userId].count++;
  });

  const topUsers = Object.entries(userMessageCounts)
    .map(([userId, data]) => ({
      userId: parseInt(userId),
      username: data.username,
      messageCount: data.count,
    }))
    .sort((a, b) => b.messageCount - a.messageCount)
    .slice(0, 10);

  return {
    totalMessages,
    activeUsers,
    averageMessageLength,
    messagesPerMinute: messagesLastMinute,
    topUsers,
  };
}

/**
 * Create chat notification
 */
export function createChatNotification(
  userId: number,
  type: 'mention' | 'reply' | 'achievement' | 'trade_request',
  fromUserId: number,
  fromUsername: string,
  roomId: string,
  messageId: string,
  content: string
): ChatNotification {
  return {
    id: `notif_${userId}_${Date.now()}`,
    userId,
    type,
    fromUserId,
    fromUsername,
    roomId,
    messageId,
    content,
    read: false,
    createdAt: new Date(),
  };
}

/**
 * Get unread notifications
 */
export function getUnreadNotifications(notifications: ChatNotification[], userId: number): ChatNotification[] {
  return notifications.filter((n) => n.userId === userId && !n.read);
}

/**
 * Mark notification as read
 */
export function markNotificationAsRead(notification: ChatNotification): void {
  notification.read = true;
}

/**
 * Get chat room activity
 */
export interface RoomActivity {
  roomId: string;
  roomName: string;
  activeMembers: number;
  messagesLastHour: number;
  messagesLastDay: number;
  topTopics: string[];
}

export function getRoomActivity(room: ChatRoom): RoomActivity {
  const now = Date.now();
  const oneHourAgo = now - 60 * 60 * 1000;
  const oneDayAgo = now - 24 * 60 * 60 * 1000;

  const messagesLastHour = room.messages.filter((m) => m.timestamp.getTime() > oneHourAgo).length;
  const messagesLastDay = room.messages.filter((m) => m.timestamp.getTime() > oneDayAgo).length;

  // Extract topics (simple word frequency)
  const words: Record<string, number> = {};
  room.messages.forEach((m) => {
    const messageWords = m.content.split(/\s+/).filter((w) => w.length > 3);
    messageWords.forEach((word) => {
      words[word.toLowerCase()] = (words[word.toLowerCase()] || 0) + 1;
    });
  });

  const topTopics = Object.entries(words)
    .sort((a, b) => b[1] - a[1])
    .slice(0, 5)
    .map(([word]) => word);

  return {
    roomId: room.id,
    roomName: room.name,
    activeMembers: room.members.length,
    messagesLastHour,
    messagesLastDay,
    topTopics,
  };
}
