import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';
import { Tasks } from '@/modules/tasks/tasks.model';
import { TaskStatus } from '@/modules/tasks/tasks.constant';
import { createNotification } from '@/modules/notification/notification.service';
import {
  NotificationStatus,
  UserType,
} from '@/modules/notification/notification.constant';
import { getObjectId } from '@/shared/utils/commonHelper';
import User from '@/modules/user/user.model';
import { Status } from '@/shared/constants/enum.constant';
import { UnitBookingOrHold } from '@/modules/activity/unitBookingOrHold/unitBookingOrHold.model';
import { Lead } from '@/modules/lead/lead.model';
import { Activity } from '@/modules/activity/activity.model';

dayjs.extend(utc);
dayjs.extend(timezone);

export const runEodWorkSummary = async () => {
  try {
    const IST = 'Asia/Kolkata';
    const startOfDay = dayjs().tz(IST).startOf('day').toDate();
    const endOfDay = dayjs().tz(IST).endOf('day').toDate();

    console.info(
      `Running EOD Work Summary for date range: ${startOfDay} to ${endOfDay}`,
    );

    const users = await User.find({ status: Status.ACTIVE }).select(
      '_id company.id',
    );

    for (const user of users) {
      if (!user.company?.id) continue;

      const summary = await Tasks.aggregate([
        {
          $match: {
            companyId: getObjectId(user.company.id),
            assignedTo: getObjectId(user._id),
            status: TaskStatus.COMPLETED,
            activityType: {
              $in: ['call', 'meeting', 'siteVisit'],
            },
            activityDate: { $gte: startOfDay, $lte: endOfDay },
          },
        },
        {
          $group: {
            _id: '$activityType',
            count: { $sum: 1 },
          },
        },
      ]);

      const counts: Record<string, number> = {
        call: 0,
        meeting: 0,
        siteVisit: 0,
      };

      summary.forEach((item) => {
        const type = item._id as string;
        if (counts[type] !== undefined) {
          counts[type] = (counts[type] || 0) + item.count;
        }
      });

      const calls = counts.call || 0;
      const meetings = counts.meeting || 0;
      const siteVisits = counts.siteVisit || 0;

      const userId = getObjectId(user._id);
      const companyId = getObjectId(user.company.id);

      const [
        bookings,
        pendingCount,
        newLeadsCount,
        existingLeadsAgg,
      ] = await Promise.all([
        UnitBookingOrHold.countDocuments({
          action: 'book',
          soldBy: userId,
          createdAt: { $gte: startOfDay, $lte: endOfDay },
        }),
        Tasks.countDocuments({
          companyId,
          assignedTo: userId,
          status: TaskStatus.PENDING,
        }),
        Lead.countDocuments({
          company: companyId,
          assignedTo: userId,
          createdAt: { $gte: startOfDay, $lte: endOfDay },
        }),
        Activity.aggregate<{ total: number }>([
          {
            $match: {
              company: companyId,
              assignedTo: userId,
              createdAt: { $gte: startOfDay, $lte: endOfDay },
              lead: { $exists: true, $ne: null },
            },
          },
          {
            $lookup: {
              from: 'leads',
              localField: 'lead',
              foreignField: '_id',
              as: 'leadDoc',
            },
          },
          { $unwind: '$leadDoc' },
          {
            $match: {
              'leadDoc.createdAt': { $lt: startOfDay },
            },
          },
          {
            $group: {
              _id: '$lead',
            },
          },
          {
            $count: 'total',
          },
        ]),
      ]);

      const existingLeadsCount = existingLeadsAgg[0]?.total ?? 0;

      const title = "Today's Work Summary";
      const body = `Calls: ${calls} • Meetings: ${meetings} • Site visits: ${siteVisits} • Bookings: ${bookings} • Left Pending: ${pendingCount} Tasks • New Leads: ${newLeadsCount} • Existing Leads: ${existingLeadsCount}.`;

      const appRedirect = {
        screenType: 'Dashboard',
      };

      await createNotification(
        {
          title,
          description: body,
          userType: UserType.SELF,
          user: getObjectId(user._id),
          status: NotificationStatus.SEND,
        },
        appRedirect,
      );
    }

    console.log('EOD Work Summary sent');
  } catch (error) {
    console.error('EOD Work Summary Error:', error);
  }
};
