import { prisma } from "@/lib/prisma";
import { createMentionNotifications } from "@/lib/notifications";
import { emitNotification } from "@/lib/socket";

/**
 * Extracts mention user IDs from HTML content
 * Looks for mentions in the format: <span class="mention" data-id="userId" data-label="userName">@userName</span>
 */
export function extractMentionIds(htmlContent: string): string[] {
  if (!htmlContent) return [];

  const mentionRegex = /<span[^>]*class="[^"]*mention[^"]*"[^>]*data-id="([^"]+)"[^>]*>/g;
  const mentions: string[] = [];
  let match;

  while ((match = mentionRegex.exec(htmlContent)) !== null) {
    const userId = match[1];
    if (userId && !mentions.includes(userId)) {
      mentions.push(userId);
    }
  }

  return mentions;
}

/**
 * Stores mentions for a task description
 */
export async function storeMentionsForTask(
  taskId: string,
  workspaceId: string,
  createdById: string,
  htmlContent: string
) {
  const mentionedUserIds = extractMentionIds(htmlContent);
  
  if (mentionedUserIds.length === 0) return;

  // Get task and creator info for notifications
  const task = await prisma.task.findUnique({
    where: { id: taskId },
    select: { name: true },
  });

  const creator = await prisma.user.findUnique({
    where: { id: createdById },
    select: { name: true, email: true },
  });

  // Remove existing mentions for this task (in case of edits)
  try {
    await (prisma as any).mention?.deleteMany({
      where: {
        taskId,
        commentId: null,
      },
    });
  } catch (error) {
    console.error("Error deleting existing mentions:", error);
  }

  // Create new mentions
  const mentionData = mentionedUserIds
    .filter(userId => userId !== createdById) // Don't mention yourself
    .map(mentionedUserId => ({
      mentionedUserId,
      createdById,
      workspaceId,
      taskId,
      commentId: null,
    }));

  if (mentionData.length > 0) {
    try {
      await (prisma as any).mention?.createMany({
        data: mentionData,
        skipDuplicates: true,
      });

      // Create notifications for mentions
      const notifications = await createMentionNotifications(
        mentionedUserIds,
        createdById,
        workspaceId,
        taskId,
        undefined, // no commentId for task mentions
        creator?.name || creator?.email,
        task?.name
      );

      // Emit real-time notifications
      for (const notification of notifications) {
        if (notification) {
          await emitNotification(notification.userId, notification);
        }
      }
    } catch (error) {
      console.error("Error creating mentions or notifications:", error);
    }
  }
}

/**
 * Stores mentions for a comment
 */
export async function storeMentionsForComment(
  commentId: string,
  taskId: string,
  workspaceId: string,
  createdById: string,
  htmlContent: string
) {
  const mentionedUserIds = extractMentionIds(htmlContent);
  
  if (mentionedUserIds.length === 0) return;

  // Get task and creator info for notifications
  const task = await prisma.task.findUnique({
    where: { id: taskId },
    select: { name: true },
  });

  const creator = await prisma.user.findUnique({
    where: { id: createdById },
    select: { name: true, email: true },
  });

  // Remove existing mentions for this comment (in case of edits)
  try {
    await (prisma as any).mention?.deleteMany({
      where: {
        commentId,
      },
    });
  } catch (error) {
    console.error("Error deleting existing mentions:", error);
  }

  // Create new mentions
  const mentionData = mentionedUserIds
    .filter(userId => userId !== createdById) // Don't mention yourself
    .map(mentionedUserId => ({
      mentionedUserId,
      createdById,
      workspaceId,
      taskId,
      commentId,
    }));

  if (mentionData.length > 0) {
    try {
      await (prisma as any).mention?.createMany({
        data: mentionData,
        skipDuplicates: true,
      });

      // Create notifications for mentions
      const notifications = await createMentionNotifications(
        mentionedUserIds,
        createdById,
        workspaceId,
        taskId,
        commentId,
        creator?.name || creator?.email,
        task?.name
      );

      // Emit real-time notifications
      for (const notification of notifications) {
        if (notification) {
          await emitNotification(notification.userId, notification);
        }
      }
    } catch (error) {
      console.error("Error creating mentions or notifications:", error);
    }
  }
}

/**
 * Gets unread mentions for a user in a workspace
 */
export async function getUnreadMentions(userId: string, workspaceId: string) {
  try {
    return await (prisma as any).mention?.findMany({
      where: {
        mentionedUserId: userId,
        workspaceId,
        isRead: false,
      },
      include: {
        task: {
          select: {
            id: true,
            name: true,
          },
        },
        comment: {
          select: {
            id: true,
            content: true,
          },
        },
        createdBy: {
          select: {
            id: true,
            name: true,
            email: true,
            image: true,
          },
        },
      },
      orderBy: {
        createdAt: 'desc',
      },
    }) || [];
  } catch (error) {
    console.error('Failed to get unread mentions:', error);
    return [];
  }
}

/**
 * Marks mentions as read
 */
export async function markMentionsAsRead(mentionIds: string[]) {
  if (mentionIds.length === 0) return;

  try {
    await (prisma as any).mention?.updateMany({
      where: {
        id: {
          in: mentionIds,
        },
      },
      data: {
        isRead: true,
      },
    });
  } catch (error) {
    console.error('Failed to mark mentions as read:', error);
  }
} 