import { prisma } from '../../config/database';
import { friendshipService } from './friendship.service';

export const integrationService = {
  /** Get friends who have signed up for a specific shift */
  async getFriendsAttendingShift(userId: string, shiftId: string) {
    const friendIds = await friendshipService.getFriendIds(userId);
    if (friendIds.length === 0) return { friends: [], count: 0 };

    // Filter out friends who hid their activity
    const hiddenIds = await this.getHiddenActivityUserIds(friendIds);
    const visibleIds = friendIds.filter((id) => !hiddenIds.has(id));
    if (visibleIds.length === 0) return { friends: [], count: 0 };

    const signups = await prisma.shiftSignup.findMany({
      where: {
        shiftId,
        userId: { in: visibleIds },
        status: 'CONFIRMED',
      },
      include: {
        user: { select: { id: true, name: true, email: true } },
      },
    });

    return {
      friends: signups.map((s) => ({
        id: s.user!.id,
        name: s.user!.name,
        email: s.user!.email,
      })),
      count: signups.length,
    };
  },

  /** Get friends who participated in a specific campaign (sent emails) */
  async getFriendsInCampaign(userId: string, campaignId: string) {
    const friendIds = await friendshipService.getFriendIds(userId);
    if (friendIds.length === 0) return { friends: [], count: 0 };

    const hiddenIds = await this.getHiddenActivityUserIds(friendIds);
    const visibleIds = friendIds.filter((id) => !hiddenIds.has(id));
    if (visibleIds.length === 0) return { friends: [], count: 0 };

    // Get distinct users who sent emails for this campaign
    const emails = await prisma.campaignEmail.findMany({
      where: {
        campaignId,
        userId: { in: visibleIds },
      },
      distinct: ['userId'],
      include: {
        user: { select: { id: true, name: true, email: true } },
      },
    });

    return {
      friends: emails
        .filter((e) => e.user)
        .map((e) => ({
          id: e.user!.id,
          name: e.user!.name,
          email: e.user!.email,
        })),
      count: emails.filter((e) => e.user).length,
    };
  },

  /** Get friends with active canvass sessions (currently canvassing) */
  async getFriendsActiveOnMap(userId: string) {
    const friendIds = await friendshipService.getFriendIds(userId);
    if (friendIds.length === 0) return { friends: [], count: 0 };

    const hiddenIds = await this.getHiddenActivityUserIds(friendIds);
    const visibleIds = friendIds.filter((id) => !hiddenIds.has(id));
    if (visibleIds.length === 0) return { friends: [], count: 0 };

    const sessions = await prisma.canvassSession.findMany({
      where: {
        userId: { in: visibleIds },
        status: 'ACTIVE',
      },
      include: {
        user: { select: { id: true, name: true, email: true } },
        cut: { select: { id: true, name: true } },
      },
    });

    return {
      friends: sessions.map((s) => ({
        id: s.user.id,
        name: s.user.name,
        email: s.user.email,
        cutName: s.cut.name,
        cutId: s.cut.id,
        startedAt: s.startedAt,
      })),
      count: sessions.length,
    };
  },

  /** Get friends who voted on a straw poll */
  async getFriendsInStrawPoll(userId: string, pollId: string) {
    const friendIds = await friendshipService.getFriendIds(userId);
    if (friendIds.length === 0) return { friends: [], count: 0 };

    const hiddenIds = await this.getHiddenActivityUserIds(friendIds);
    const visibleIds = friendIds.filter((id) => !hiddenIds.has(id));
    if (visibleIds.length === 0) return { friends: [], count: 0 };

    const votes = await prisma.strawPollVote.findMany({
      where: {
        pollId,
        userId: { in: visibleIds },
      },
      distinct: ['userId'],
      include: {
        user: { select: { id: true, name: true, email: true } },
      },
    });

    return {
      friends: votes
        .filter((v) => v.user)
        .map((v) => ({
          id: v.user!.id,
          name: v.user!.name,
          email: v.user!.email,
        })),
      count: votes.filter((v) => v.user).length,
    };
  },

  /** Helper: get user IDs that have showInFriendActivity disabled */
  async getHiddenActivityUserIds(userIds: string[]): Promise<Set<string>> {
    const hidden = await prisma.privacySettings.findMany({
      where: { userId: { in: userIds }, showInFriendActivity: false },
      select: { userId: true },
    });
    return new Set(hidden.map((p) => p.userId));
  },
};
