/**
 * Social Features Service
 * Manages friends, chat, and social interactions
 */

export interface Friend {
  userId: number;
  friendId: number;
  friendName: string;
  friendAvatar?: string;
  status: "pending" | "accepted" | "blocked";
  addedDate: string;
  lastInteraction: string;
}

export interface ChatMessage {
  id: string;
  senderId: number;
  senderName: string;
  recipientId: number;
  message: string;
  timestamp: string;
  read: boolean;
}

export interface SocialProfile {
  userId: number;
  userName: string;
  avatar?: string;
  bio?: string;
  totalFriends: number;
  totalMessages: number;
  lastActive: string;
  socialStats: {
    totalWins: number;
    totalTournaments: number;
    vipTier: string;
    favoriteGame: string;
  };
}

// Storage
const friendsList: Map<number, Friend[]> = new Map();
const chatMessages: Map<string, ChatMessage[]> = new Map();
const socialProfiles: Map<number, SocialProfile> = new Map();

/**
 * Send friend request
 */
export function sendFriendRequest(
  userId: number,
  targetUserId: number,
  targetUserName: string
): { success: boolean; message: string } {
  if (userId === targetUserId) {
    return { success: false, message: "Cannot add yourself as friend" };
  }

  const userFriends = friendsList.get(userId) || [];
  const alreadyFriends = userFriends.some((f) => f.friendId === targetUserId);

  if (alreadyFriends) {
    return { success: false, message: "Already friends with this user" };
  }

  const friend: Friend = {
    userId,
    friendId: targetUserId,
    friendName: targetUserName,
    status: "pending",
    addedDate: new Date().toISOString(),
    lastInteraction: new Date().toISOString(),
  };

  userFriends.push(friend);
  friendsList.set(userId, userFriends);

  return { success: true, message: "Friend request sent" };
}

/**
 * Accept friend request
 */
export function acceptFriendRequest(userId: number, friendId: number): { success: boolean; message: string } {
  const userFriends = friendsList.get(userId) || [];
  const friend = userFriends.find((f) => f.friendId === friendId && f.status === "pending");

  if (!friend) {
    return { success: false, message: "Friend request not found" };
  }

  friend.status = "accepted";
  friend.lastInteraction = new Date().toISOString();

  // Also add reverse friendship
  const friendFriends = friendsList.get(friendId) || [];
  const reverseFriend: Friend = {
    userId: friendId,
    friendId: userId,
    friendName: friend.friendName,
    status: "accepted",
    addedDate: new Date().toISOString(),
    lastInteraction: new Date().toISOString(),
  };

  friendFriends.push(reverseFriend);
  friendsList.set(friendId, friendFriends);

  return { success: true, message: "Friend request accepted" };
}

/**
 * Remove friend
 */
export function removeFriend(userId: number, friendId: number): boolean {
  const userFriends = friendsList.get(userId) || [];
  const index = userFriends.findIndex((f) => f.friendId === friendId);

  if (index >= 0) {
    userFriends.splice(index, 1);
    friendsList.set(userId, userFriends);
    return true;
  }

  return false;
}

/**
 * Get friends list
 */
export function getFriendsList(userId: number, status: "pending" | "accepted" | "blocked" = "accepted"): Friend[] {
  const userFriends = friendsList.get(userId) || [];
  return userFriends.filter((f) => f.status === status);
}

/**
 * Send chat message
 */
export function sendChatMessage(
  senderId: number,
  senderName: string,
  recipientId: number,
  message: string
): ChatMessage {
  const conversationKey = [senderId, recipientId].sort().join("_");
  const messages = chatMessages.get(conversationKey) || [];

  const chatMessage: ChatMessage = {
    id: `msg_${Date.now()}`,
    senderId,
    senderName,
    recipientId,
    message,
    timestamp: new Date().toISOString(),
    read: false,
  };

  messages.push(chatMessage);
  chatMessages.set(conversationKey, messages);

  return chatMessage;
}

/**
 * Get chat history
 */
export function getChatHistory(userId: number, friendId: number, limit: number = 50): ChatMessage[] {
  const conversationKey = [userId, friendId].sort().join("_");
  const messages = chatMessages.get(conversationKey) || [];

  // Mark as read
  messages.forEach((m) => {
    if (m.recipientId === userId) {
      m.read = true;
    }
  });

  return messages.slice(-limit);
}

/**
 * Get unread message count
 */
export function getUnreadMessageCount(userId: number): number {
  let unreadCount = 0;

  chatMessages.forEach((messages) => {
    messages.forEach((m) => {
      if (m.recipientId === userId && !m.read) {
        unreadCount++;
      }
    });
  });

  return unreadCount;
}

/**
 * Create or update social profile
 */
export function updateSocialProfile(
  userId: number,
  userName: string,
  bio?: string,
  avatar?: string,
  stats?: any
): SocialProfile {
  let profile = socialProfiles.get(userId);

  if (!profile) {
    profile = {
      userId,
      userName,
      bio,
      avatar,
      totalFriends: 0,
      totalMessages: 0,
      lastActive: new Date().toISOString(),
      socialStats: {
        totalWins: 0,
        totalTournaments: 0,
        vipTier: "Bronze",
        favoriteGame: "Unknown",
      },
    };
  } else {
    if (bio) profile.bio = bio;
    if (avatar) profile.avatar = avatar;
    profile.lastActive = new Date().toISOString();
    if (stats) profile.socialStats = stats;
  }

  profile.totalFriends = (friendsList.get(userId) || []).filter((f) => f.status === "accepted").length;

  socialProfiles.set(userId, profile);
  return profile;
}

/**
 * Get social profile
 */
export function getSocialProfile(userId: number): SocialProfile | undefined {
  return socialProfiles.get(userId);
}

/**
 * Block user
 */
export function blockUser(userId: number, targetUserId: number): boolean {
  const userFriends = friendsList.get(userId) || [];
  const friend = userFriends.find((f) => f.friendId === targetUserId);

  if (friend) {
    friend.status = "blocked";
    return true;
  }

  return false;
}

/**
 * Unblock user
 */
export function unblockUser(userId: number, targetUserId: number): boolean {
  const userFriends = friendsList.get(userId) || [];
  const friend = userFriends.find((f) => f.friendId === targetUserId && f.status === "blocked");

  if (friend) {
    friend.status = "accepted";
    return true;
  }

  return false;
}

/**
 * Get blocked users
 */
export function getBlockedUsers(userId: number): Friend[] {
  const userFriends = friendsList.get(userId) || [];
  return userFriends.filter((f) => f.status === "blocked");
}

/**
 * Share win on social media
 */
export function createShareableWinLink(
  userId: number,
  userName: string,
  gameName: string,
  winAmount: number,
  multiplier: number
): string {
  const shareData = {
    player: userName,
    game: gameName,
    win: winAmount,
    multiplier: multiplier,
    timestamp: Date.now(),
  };

  const encoded = Buffer.from(JSON.stringify(shareData)).toString("base64");
  return `https://playplaycoinkrazy.com/share/${encoded}`;
}

/**
 * Get social recommendations (friends to add)
 */
export function getSocialRecommendations(userId: number, limit: number = 5): SocialProfile[] {
  const userFriends = friendsList.get(userId) || [];
  const friendIds = userFriends.map((f) => f.friendId);

  const recommendations: SocialProfile[] = [];

  socialProfiles.forEach((profile) => {
    if (profile.userId !== userId && !friendIds.includes(profile.userId)) {
      recommendations.push(profile);
    }
  });

  // Sort by last active
  recommendations.sort((a, b) => new Date(b.lastActive).getTime() - new Date(a.lastActive).getTime());

  return recommendations.slice(0, limit);
}
