import dayjs from 'dayjs';

import { sendMeetingWhatsApp } from '@/modules/tasks/tasks.helper';
import { Tasks } from '@/modules/tasks/tasks.model';
import { TaskStatus } from '@/modules/tasks/tasks.constant';

export const notify2hoursUpcomingActivities = async () => {
  try {
    const now = dayjs();
    const targetTimeStart = now.add(2, 'hour').startOf('minute').toDate();
    const targetTimeEnd = now.add(2, 'hour').endOf('minute').toDate();

    const tasksToNotify = await Tasks.aggregate([
      {
        $match: {
          activityDate: { $gte: targetTimeStart, $lte: targetTimeEnd },
        },
      },
      {
        $lookup: {
          from: 'companies',
          localField: 'companyId',
          foreignField: '_id',
          as: 'company',
        },
      },
      { $unwind: '$company' },
      { $match: { 'company.status': 'active' } },
    ]);

    const promises = tasksToNotify.map((task) =>
      sendMeetingWhatsApp({
        data: task,
        taskId: task._id,
        triggerPoint: 'Before2Hours',
        assignDate: true,
        activityType: task.activityType,
      }),
    );

    await Promise.all(promises);

    console.info(
      `✅ Sent WhatsApp notifications for ${tasksToNotify.length} tasks`,
    );
  } catch (error) {
    console.error('❌ Error in notifyUpcomingActivities cron job:', error);
  }
};

const activityBaseTriggerPoints = {
  meeting: 'NoActivityScheduled',
  siteVisit: 'NoActivityScheduledSiteVisit',
};

const getTriggerPointLabel = (activityType: string, days: number): string => {
  const base = activityBaseTriggerPoints[activityType];
  if (!base) throw new Error(`Unsupported activityType: ${activityType}`);
  return `After${days}Days${base}`;
};

export const checkCompletedTasksAndNotify = async (daysToCheck: number) => {
  try {
    const activityTypes = Object.keys(activityBaseTriggerPoints);
    const cutoffDate = dayjs().subtract(daysToCheck, 'day').toDate();

    // Aggregate tasks with left-joined activities updated after cutoffDate
    const tasksWithActivityInfo = await Tasks.aggregate([
      {
        $match: {
          status: TaskStatus.COMPLETED,
          activityType: { $in: activityTypes },
          updatedAt: { $lte: cutoffDate }, // Tasks updated at least daysToCheck ago
        },
      },
      {
        $lookup: {
          from: 'activities',
          let: { taskId: '$_id' },
          pipeline: [
            {
              $match: {
                $expr: {
                  $and: [
                    { $eq: ['$task', '$$taskId'] },
                    { $gt: ['$updatedAt', cutoffDate] },
                  ],
                },
              },
            },
          ],
          as: 'recentActivities',
        },
      },
      {
        $match: {
          recentActivities: { $size: 0 }, // No recent activities after cutoffDate
        },
      },
    ]);

    // Send notifications for filtered tasks
    if (
      Array.isArray(tasksWithActivityInfo) &&
      tasksWithActivityInfo.length > 0
    ) {
      const notifications = tasksWithActivityInfo?.map((task) =>
        sendMeetingWhatsApp({
          data: task,
          taskId: task._id,
          triggerPoint: getTriggerPointLabel(task.activityType, daysToCheck),
          assignDate: true,
          activityType: task.activityType,
        }),
      );

      await Promise.all(notifications);
    } else {
      console.info('No tasks found to send notifications for.');
    }

    console.info(
      `✅ Sent WhatsApp for ${tasksWithActivityInfo.length} tasks without activity post ${daysToCheck} days.`,
    );
  } catch (error) {
    console.error('❌ Error in checkCompletedTasksAndNotify:', error);
  }
};
