import { PipelineStage, UpdateQuery } from 'mongoose';
import mongoose from 'mongoose';
import dayjs from 'dayjs';

import { ApiError } from '@/shared/utils/errors';
import { defaultStatus } from '@/shared/utils/responseCode/httpStatusAlias';
import { Tasks } from '@/modules/tasks/tasks.model';
import {
  ITasksDoc,
  NewCreatedTasks,
  PopulatedTask,
  UpdateTasksBody,
} from '@/modules/tasks/tasks.interface';
import responseCodes from '@/shared/utils/responseCode/responseCode';
import { escapeRegex, getObjectId } from '@/shared/utils/commonHelper';
import { validateCustomFields } from '@/shared/utils/customFieldValidation';
import { CustomFormNames } from '../customFields/customFields.constant';
import {
  getPopulatedTask,
  handleLeadUpdateFromTask,
  handleTaskCompletionUpdate,
  sendMail,
  sendMeetingWhatsApp,
} from './tasks.helper';
import { TaskActivityType, TaskStatus } from './tasks.constant';
import { ActivityStatus } from '@/shared/constants/enum.constant';
import { Activity } from '../activity/activity.model';
import { updateActivity as updateActivityService } from '../activity/activity.service';
import { safeDeleteById } from '@/shared/utils/guard/ref-guard';
import { createNotification } from '../notification/notification.service';
import {
  NotificationStatus,
  NotificationType,
  UserType,
} from '../notification/notification.constant';
import { generateNotifyAtDatesDynamic } from '@/shared/utils/date';
import { getEntityByIdWithQueryString } from '@/shared/utils/modelPopulateFields';
import { ActivityRemainder } from '../activity/activityRemainder/activityRemainder.model';

const { TasksResponseCodes } = responseCodes;

export const createTasks = async (
  data: NewCreatedTasks,
): Promise<ITasksDoc> => {
  const customFields = await validateCustomFields({
    customFields: data.customFields,
    companyId: data.companyId,
    formName: CustomFormNames.TASKS,
    errorCode: TasksResponseCodes.TASKS_INVALID_CUSTOM_FIELDS,
    section: data.activityType,
  });
  console.log('🚀 ~ createTasks ~ customFields:', customFields);

  const notifyAt = await generateNotifyAtDatesDynamic(
    data.activityDate,
    [-30, 15],
  );

  data = {
    ...data,
    ...(customFields && { customFields }),
    ...(notifyAt && { notifyAt }),
  };
  const createdTask = await Tasks.create(data);
  const tasks = await Tasks.findById(createdTask._id)
    .populate([
      {
        path: 'assignedTo',
        select: 'firstName lastName profileImage',
      },
      {
        path: 'createdBy',
        select: 'firstName lastName profileImage',
      },
    ])
    .lean<PopulatedTask>();

  if (!tasks)
    throw new ApiError(
      defaultStatus.CONFLICT,
      'Failed to create tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );

  await handleLeadUpdateFromTask(createdTask);

  if (
    createdTask.assignedTo &&
    createdTask.createdBy &&
    !createdTask.assignedTo.equals(createdTask.createdBy)
  ) {
    const appRedirect = {
      screenType: 'Tasks_Details',
      id: tasks._id,
    };

    const taskActivitydate = dayjs(tasks.activityDate).format('DD-MM-YYYY');
    const description = `${tasks.createdBy.firstName} ${tasks.createdBy.lastName} assigned you a task: ${tasks.activityType} with ${tasks.assignedTo.firstName} ${tasks.assignedTo.lastName} due on ${taskActivitydate}`;

    await Promise.all([
      sendMail(createdTask._id),
      createNotification(
        {
          title: 'New Task Assigned',
          description,
          userType: UserType.SELF,
          user: getObjectId(createdTask.assignedTo),
          status: NotificationStatus.SEND,
          notificationType: NotificationType.ALERT,
        },
        appRedirect,
      ),
    ]);
  }

  if (
    data.activityType === TaskActivityType.MEETING ||
    data.activityType === TaskActivityType.SITE_VISIT
  )
    await sendMeetingWhatsApp({
      data,
      taskId: tasks._id,
      triggerPoint: 'OnSchedule',
      assignDate: true,
      activityType: data.activityType,
    });

  return createdTask;
};

export const getTasksById = async (
  id: string,
  fields?: string,
  populate?: string,
) => {
  const tasks = await getEntityByIdWithQueryString({
    model: Tasks,
    entityId: id,
    fields,
    populate,
    responseCode: TasksResponseCodes.TASKS_NOT_FOUND,
  });

  const activity = await Activity.findOne({ task: tasks._id }).select('_id');
  if (activity) {
    (tasks as any).activityId = activity._id;
  }

  return tasks;
};

export const updateTasks = async (
  id: string,
  updateData: UpdateTasksBody,
): Promise<boolean> => {
  try {
    const existingTask = await Tasks.findOne({
      _id: id,
      companyId: updateData.companyId,
    }).exec();

    if (!existingTask)
      throw new ApiError(
        defaultStatus.OK,
        'Tasks not found',
        true,
        '',
        TasksResponseCodes.TASKS_NOT_FOUND,
      );

    updateData = {
      ...updateData,
      ...(updateData.project && { project: getObjectId(updateData.project) }),
      ...(updateData.property && {
        property: getObjectId(updateData.property),
      }),
    };

    if (updateData.status !== TaskStatus.COMPLETED) {
      const customFields = await validateCustomFields({
        customFields: updateData.customFields,
        companyId: updateData.companyId,
        formName: CustomFormNames.TASKS,
        errorCode: TasksResponseCodes.TASKS_INVALID_CUSTOM_FIELDS,
        section: updateData.activityType,
      });
      updateData = {
        ...updateData,
        ...(customFields && { customFields }),
      };
    }

    const updateQuery: UpdateQuery<ITasksDoc> = { $set: updateData };

    if (updateData.contactId) updateQuery.$unset = { leadId: '' };
    else if (updateData.leadId) updateQuery.$unset = { contactId: '' };

    const oldDate = dayjs(existingTask?.activityDate);
    const newDate = dayjs(updateData?.activityDate);

    if (
      newDate &&
      oldDate &&
      newDate > oldDate &&
      updateData.status !== TaskStatus.COMPLETED
    )
      updateData = {
        ...updateData,
        status: TaskStatus.PENDING,
      };

    const result = await Tasks.findOneAndUpdate(
      { _id: id, companyId: updateData.companyId },
      updateData,
      {
        new: true,
        runValidators: true,
        strict: false,
      },
    ).exec();

    if (!result)
      throw new ApiError(
        defaultStatus.OK,
        'Tasks not found',
        true,
        '',
        TasksResponseCodes.TEAM_NOT_FOUND,
      );

    if (
      result.assignedTo &&
      result.createdBy &&
      !result.assignedTo.equals(result.createdBy)
    ) {
      const appRedirect = {
        screenType: 'Tasks_Details',
        id: id,
      };

      const tasks = await getPopulatedTask({ taskId: id });

      const taskActivitydate = dayjs(result.activityDate).format('DD-MM-YYYY');
      const description = `${tasks.createdBy.firstName} ${tasks.createdBy.lastName} assigned you a task: ${tasks.activityType} with ${tasks.assignedTo.firstName} ${tasks.assignedTo.lastName} due on ${taskActivitydate}`;

      await Promise.all([
        sendMail(result._id),
        createNotification(
          {
            title: 'New Task Assigned',
            description,
            userType: UserType.SELF,
            user: getObjectId(result.assignedTo),
            status: NotificationStatus.SEND,
            notificationType: NotificationType.ALERT,
          },
          appRedirect,
        ),
      ]);
    }

    if (!oldDate.isSame(newDate))
      await sendMeetingWhatsApp({
        data: updateData,
        taskId: id,
        triggerPoint: 'WhenMeetingRescheduled',
        assignDate: true,
        activityType: result.activityType,
      });

    if (result.status === TaskStatus.COMPLETED) {
      const activity = await Activity.findOne({
        task: result._id,
        company: result.companyId,
      })
        .select('_id')
        .lean();

      if (activity?._id)
        await updateActivityService(activity._id.toString(), {
          status: ActivityStatus.COMPLETED,
        });

      if (activity)
        await ActivityRemainder.findOneAndUpdate(
          { activityId: getObjectId(activity._id.toString()) },
          { $set: { status: ActivityStatus.COMPLETED } },
          { new: true },
        ).exec();

      if (
        result.activityType === TaskActivityType.MEETING ||
        result.activityType === TaskActivityType.SITE_VISIT
      )
        await sendMeetingWhatsApp({
          data: updateData,
          taskId: id,
          triggerPoint: 'AfterMeetingCompletedSuccessfully',
          assignDate: true,
          activityType: result.activityType,
        });
    }

    await handleTaskCompletionUpdate(result);

    return true;
  } catch (err) {
    console.log('🚀 ~ updateTasks ~ err:', err);
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.OK,
      'Failed to update tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  }
};

export const deleteTasks = async (id: string): Promise<boolean> => {
  try {
    const activities = await Activity.find({ task: id }).select('_id').lean();
    const activityIds = activities.map((activity) => activity._id.toString());

    await safeDeleteById(Tasks, id, TasksResponseCodes.TASKS_IN_USE);

    if (activityIds.length > 0) {
      await ActivityRemainder.deleteMany({
        activityId: { $in: activityIds },
      }).exec();

      await Activity.deleteMany({ task: id }).exec();
    }

    return true;
  } catch (err) {
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.OK,
      'Failed to delete tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  }
};

export const bulkUpdateTasks = async (
  ids: string[],
  updateData: UpdateTasksBody,
  assignedBody: { firstName: string; lastName: string },
): Promise<ITasksDoc[]> => {
  try {
    // Filter out empty values
    const filteredUpdateData = Object.fromEntries(
      Object.entries(updateData).filter(
        ([_, value]) => value !== undefined && value !== '',
      ),
    );

    // Validate that all tasks exist and belong to the company
    const existingTasks = await Tasks.find({
      _id: { $in: ids },
      companyId: updateData.companyId,
    })
      .select('assignedTo createdBy status activityType')
      .lean();

    if (existingTasks.length !== ids.length) {
      throw new ApiError(
        defaultStatus.NOT_FOUND,
        'One or more tasks not found',
        true,
        '',
        TasksResponseCodes.TASKS_NOT_FOUND,
      );
    }

    // Validate custom fields if status is not completed
    if (
      filteredUpdateData.status !== TaskStatus.COMPLETED &&
      filteredUpdateData.customFields
    ) {
      const customFields = await validateCustomFields({
        customFields: filteredUpdateData.customFields,
        companyId: updateData.companyId,
        formName: CustomFormNames.TASKS,
        errorCode: TasksResponseCodes.TASKS_INVALID_CUSTOM_FIELDS,
        section: filteredUpdateData.activityType,
      });
      filteredUpdateData.customFields = customFields;
    }

    // Handle project and property ID conversion
    if (filteredUpdateData.project) {
      filteredUpdateData.project = getObjectId(
        filteredUpdateData.project as string,
      );
    }
    if (filteredUpdateData.property) {
      filteredUpdateData.property = getObjectId(
        filteredUpdateData.property as string,
      );
    }

    // Perform bulk update
    const result = await Tasks.updateMany(
      { _id: { $in: ids }, companyId: updateData.companyId },
      {
        ...filteredUpdateData,
        updatedAt: new Date(),
      },
      {
        runValidators: true,
        strict: false,
      },
    );

    if (result.modifiedCount === 0) {
      throw new ApiError(
        defaultStatus.INTERNAL_SERVER_ERROR,
        'Failed to update tasks',
        true,
        '',
        TasksResponseCodes.TASKS_ERROR,
      );
    }

    // Get updated tasks for return
    const updatedTasks = await Tasks.find({
      _id: { $in: ids },
      companyId: updateData.companyId,
    })
      .populate([
        {
          path: 'assignedTo',
          select: 'firstName lastName profileImage',
        },
        {
          path: 'createdBy',
          select: 'firstName lastName profileImage',
        },
      ])
      .lean<PopulatedTask[]>();

    // Handle notifications for assignedTo changes
    if (filteredUpdateData.assignedTo) {
      const task = await getPopulatedTask({ taskId: ids[0] });
      const taskActivitydate = dayjs(task?.activityDate).format('DD-MM-YYYY');

      const description = `${assignedBody.firstName} ${assignedBody.lastName} assigned you multiple tasks due on ${taskActivitydate}`;

      await createNotification(
        {
          title: 'Multiple Tasks Assigned',
          description,
          userType: UserType.SELF,
          user: getObjectId(filteredUpdateData.assignedTo as string),
          status: NotificationStatus.SEND,
          notificationType: NotificationType.ALERT,
        },
        {
          screenType: 'Tasks_List',
          id: null,
        },
      );
    }

    // Handle notifications for status changes to completed
    if (filteredUpdateData.status === TaskStatus.COMPLETED) {
      // Update associated activities to completed
      const activities = await Activity.find({
        task: { $in: ids },
        company: updateData.companyId,
      })
        .select('_id')
        .lean();

      if (activities.length > 0) {
        // Update each activity individually
        await Promise.all(
          activities.map((activity) =>
            updateActivityService(activity._id.toString(), {
              completionNote: updateData.notes,
              status: ActivityStatus.COMPLETED,
            }),
          ),
        );

        const activityIds = activities.map((a) => a._id.toString());

        await ActivityRemainder.updateMany(
          { activityId: { $in: activityIds } },
          { $set: { status: ActivityStatus.COMPLETED } },
        ).exec();
      }

      // Notify the user who completed the tasks
      await createNotification(
        {
          title: 'Multiple Tasks Completed',
          description: `${updatedTasks.length} task(s) marked as completed`,
          userType: UserType.SELF,
          user: getObjectId(updateData.updatedBy as string),
          status: NotificationStatus.SEND,
        },
        {
          screenType: 'Tasks_List',
          id: null,
        },
      );
    }

    return updatedTasks as ITasksDoc[];
  } catch (err) {
    console.log('🚀 ~ bulkUpdateTasks ~ err:', err);
    if (err instanceof ApiError) throw err;
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to bulk update tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  }
};

export const bulkDeleteTasks = async (
  taskIds: string[],
): Promise<{ deletedCount: number }> => {
  if (!taskIds || taskIds.length < 1)
    throw new ApiError(
      defaultStatus.BAD_REQUEST,
      'At least one task ID is required',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );

  const session = await mongoose.startSession();
  session.startTransaction();

  try {
    // First, find all activities associated with these tasks (before deletion)
    const activities = await Activity.find({ task: { $in: taskIds } })
      .select('_id')
      .lean();
    const activityIds = activities.map((activity) => activity._id.toString());

    // Delete the tasks themselves first (this validates each task)
    for (const taskId of taskIds) {
      await safeDeleteById(Tasks, taskId, TasksResponseCodes.TASKS_IN_USE);
    }

    // Only after all tasks are successfully deleted, delete associated activities and reminders
    if (activityIds.length > 0) {
      await ActivityRemainder.deleteMany({
        activityId: { $in: activityIds },
      }).exec();

      await Activity.deleteMany({ task: { $in: taskIds } }).exec();
    }

    await session.commitTransaction();
    return { deletedCount: taskIds.length };
  } catch (error) {
    await session.abortTransaction();
    if (error instanceof ApiError) throw error;
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to bulk delete tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  } finally {
    session.endSession();
  }
};

export const queryTasksForExport = async (
  filter: Record<string, string> = {},
) => {
  try {
    const {
      search,
      status,
      activityType,
      contactId,
      leadId,
      assignedTo,
      companyId,
      activityDate,
      dueDateFrom,
      dueDateTo,
      taskIds,
    } = filter;

    const baseMatch: Record<string, unknown> = {};
    // if (status)
    //   baseMatch.status = status === 'all' ? { $ne: 'completed' } : status;

    // if (activityType && activityType !== 'all')
    //   baseMatch.activityType = activityType;

    // STATUS FILTER
    if (status && typeof status === 'string') {
      if (status === 'all') {
        baseMatch.status = { $ne: 'completed' };
      } else if (status.includes(',')) {
        baseMatch.status = {
          $in: status.split(',').map((s) => s.trim()),
        };
      } else {
        baseMatch.status = status;
      }
    }

    // ACTIVITY TYPE FILTER
    if (activityType && typeof activityType === 'string') {
      if (activityType !== 'all') {
        if (activityType.includes(',')) {
          baseMatch.activityType = {
            $in: activityType.split(',').map((t) => t.trim()),
          };
        } else {
          baseMatch.activityType = activityType;
        }
      }
    }

    if (contactId) baseMatch.contactId = getObjectId(contactId);
    if (companyId) baseMatch.companyId = getObjectId(companyId);
    if (leadId) baseMatch.leadId = getObjectId(leadId);
    if (assignedTo && typeof assignedTo === 'string') {
      if (assignedTo.includes(',')) {
        baseMatch.assignedTo = {
          $in: assignedTo.split(',').map((id) => getObjectId(id.trim())),
        };
      } else {
        baseMatch.assignedTo = getObjectId(assignedTo);
      }
    }
    // console.log("tasks assignes",JSON.stringify(baseMatch.assignedTo,null,2))

    // Add taskIds filter if provided
    if (taskIds) {
      const idsArray = Array.isArray(taskIds) ? taskIds : taskIds.split(',');
      baseMatch._id = { $in: idsArray.map((id: string) => getObjectId(id)) };
    }

    const pipeline: PipelineStage[] = [
      { $match: baseMatch },

      {
        $lookup: {
          from: 'contacts',
          localField: 'contactId',
          foreignField: '_id',
          as: 'directContact',
        },
      },
      {
        $unwind: {
          path: '$directContact',
          preserveNullAndEmptyArrays: true,
        },
      },

      {
        $lookup: {
          from: 'leads',
          localField: 'leadId',
          foreignField: '_id',
          as: 'leadDoc',
        },
      },
      {
        $unwind: {
          path: '$leadDoc',
          preserveNullAndEmptyArrays: true,
        },
      },
      {
        $lookup: {
          from: 'contacts',
          localField: 'leadDoc.contact',
          foreignField: '_id',
          as: 'leadContact',
        },
      },
      {
        $unwind: {
          path: '$leadContact',
          preserveNullAndEmptyArrays: true,
        },
      },

      {
        $addFields: {
          contact: {
            $ifNull: ['$directContact', '$leadContact'],
          },
        },
      },

      ...[
        { from: 'users', localField: 'assignedTo', as: 'assignedUser' },
        { from: 'users', localField: 'createdBy', as: 'createdByUser' },
      ].flatMap(({ from, localField, as }) => [
        {
          $lookup: { from, localField, foreignField: '_id', as },
        },
        {
          $unwind: { path: `$${as}`, preserveNullAndEmptyArrays: true },
        },
      ]),
      {
        $addFields: {
          'leadDoc.projectObjectId': {
            $cond: {
              if: { $ne: ['$leadDoc.project', null] },
              then: { $toObjectId: { $toString: '$leadDoc.project' } },
              else: null,
            },
          },
          'leadDoc.unitObjectId': {
            $cond: {
              if: { $ne: ['$leadDoc.unit', null] },
              then: { $toObjectId: { $toString: '$leadDoc.unit' } },
              else: null,
            },
          },
        },
      },
      {
        $lookup: {
          from: 'projects',
          localField: 'leadDoc.projectObjectId',
          foreignField: '_id',
          as: 'projectDoc',
        },
      },
      { $unwind: { path: '$projectDoc', preserveNullAndEmptyArrays: true } },
      {
        $lookup: {
          from: 'units',
          localField: 'leadDoc.unitObjectId',
          foreignField: '_id',
          as: 'unitDoc',
        },
      },
      { $unwind: { path: '$unitDoc', preserveNullAndEmptyArrays: true } },
      // Add property lookup for site-visit tasks
      {
        $lookup: {
          from: 'individualproperties',
          localField: 'property',
          foreignField: '_id',
          as: 'propertyDoc',
        },
      },
      { $unwind: { path: '$propertyDoc', preserveNullAndEmptyArrays: true } },
      {
        $addFields: {
          property: {
            $ifNull: ['$propertyDoc', null],
          },
        },
      },
      {
        $lookup: {
          from: 'sources',
          localField: 'leadDoc.source',
          foreignField: '_id',
          as: 'contactSourceDoc',
        },
      },
      {
        $unwind: {
          path: '$contactSourceDoc',
          preserveNullAndEmptyArrays: true,
        },
      },
      {
        $addFields: {
          'contact.source': {
            id: '$contactSourceDoc._id',
            name: '$contactSourceDoc.name',
          },
        },
      },
      {
        $lookup: {
          from: 'configurations',
          localField: 'leadDoc.configuration',
          foreignField: '_id',
          as: 'configurationDoc',
        },
      },
      {
        $lookup: {
          from: 'localities',
          localField: 'leadDoc.preferredLocalities',
          foreignField: '_id',
          as: 'localityDoc',
        },
      },
    ];

    if (search && search.trim()) {
      const term = escapeRegex(search.trim());
      const parts = term.split(/\s+/);

      if (parts.length === 1) {
        pipeline.push({
          $match: {
            $or: [
              { 'contact.firstName': { $regex: parts[0], $options: 'i' } },
              { 'contact.lastName': { $regex: parts[0], $options: 'i' } },
            ],
          },
        });
      } else {
        const regexStr = parts.join('.*');
        pipeline.push({
          $match: {
            $expr: {
              $regexMatch: {
                input: {
                  $concat: ['$contact.firstName', ' ', '$contact.lastName'],
                },
                regex: regexStr,
                options: 'i',
              },
            },
          },
        });
      }
    }

    if (activityDate)
      pipeline.push({
        $match: {
          $expr: {
            $eq: [
              { $dateToString: { format: '%d-%m-%Y', date: '$activityDate' } },
              activityDate,
            ],
          },
        },
      });

    if (dueDateFrom || dueDateTo) {
      const dateFilter: any = {};
      if (dueDateFrom) dateFilter.$gte = new Date(dueDateFrom);
      if (dueDateTo) dateFilter.$lte = new Date(dueDateTo);
      pipeline.push({
        $match: {
          activityDate: dateFilter,
        },
      });
    }

    pipeline.push({
      $project: {
        _id: 1,
        activityType: 1,
        activityDate: 1,
        notes: 1,
        callStatus: 1,
        location: 1,
        activityName: 1,
        status: 1,
        companyId: 1,

        'contact.id': '$contact._id',
        'contact.firstName': '$contact.firstName',
        'contact.lastName': '$contact.lastName',
        'contact.phone': '$contact.phone',
        'contact.source.id': '$contact.source.id',
        'contact.source.name': '$contact.source.name',

        'assignedUser.id': '$assignedUser._id',
        'assignedUser.firstName': '$assignedUser.firstName',
        'assignedUser.lastName': '$assignedUser.lastName',
        'createdByUser.id': '$createdByUser._id',
        'createdByUser.firstName': '$createdByUser.firstName',
        'createdByUser.lastName': '$createdByUser.lastName',

        'project.id': '$projectDoc._id',
        'project.projectName': '$projectDoc.projectName',

        'unit.id': '$unitDoc._id',
        'unit.unitNumber': '$unitDoc.unitNumber',

        configuration: '$configurationDoc.name',

        locality: '$localityDoc.name',

        leadScore: '$leadDoc.leadScore',
        leadId: 1,
        contactId: 1,
        createdAt: 1,
        updatedAt: 1,
      },
    });

    const result = await Tasks.aggregate(pipeline);
    return result;
  } catch (_error) {
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to fetch tasks for export',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  }
};

// TODO: can optimised pipeline

export const queryTasks = async (
  filter: Record<string, string> = {},
  options = {},
) => {
  try {
    const {
      search,
      status,
      activityType,
      contactId,
      leadId,
      assignedTo,
      companyId,
      activityDate,
      dueDateFrom,
      dueDateTo,
    } = filter;

    const baseMatch: Record<string, unknown> = {};
    // if (status)
    //   baseMatch.status = status === 'all' ? { $ne: 'completed' } : status;

    // if (activityType && activityType !== 'all')
    //   baseMatch.activityType = activityType;

    //  STATUS FILTER
    if (status && typeof status === 'string') {
      if (status === 'all') {
        baseMatch.status = { $ne: 'completed' };
      } else if (status.includes(',')) {
        baseMatch.status = {
          $in: status.split(',').map((s) => s.trim()),
        };
      } else {
        baseMatch.status = status;
      }
    }

    //  ACTIVITY TYPE FILTER
    if (activityType && typeof activityType === 'string') {
      if (activityType !== 'all') {
        if (activityType.includes(',')) {
          baseMatch.activityType = {
            $in: activityType.split(',').map((t) => t.trim()),
          };
        } else {
          baseMatch.activityType = activityType;
        }
      }
    }

    if (contactId) baseMatch.contactId = getObjectId(contactId);
    if (companyId) baseMatch.companyId = getObjectId(companyId);
    if (leadId) baseMatch.leadId = getObjectId(leadId);
    if (assignedTo && typeof assignedTo === 'string') {
      if (assignedTo.includes(',')) {
        baseMatch.assignedTo = {
          $in: assignedTo.split(',').map((id) => getObjectId(id.trim())),
        };
      } else {
        baseMatch.assignedTo = getObjectId(assignedTo);
      }
    }

    const pipeline: PipelineStage[] = [
      { $match: baseMatch },

      {
        $lookup: {
          from: 'contacts',
          localField: 'contactId',
          foreignField: '_id',
          as: 'directContact',
        },
      },
      {
        $unwind: {
          path: '$directContact',
          preserveNullAndEmptyArrays: true,
        },
      },

      {
        $lookup: {
          from: 'leads',
          localField: 'leadId',
          foreignField: '_id',
          as: 'leadDoc',
        },
      },
      {
        $unwind: {
          path: '$leadDoc',
          preserveNullAndEmptyArrays: true,
        },
      },
      {
        $lookup: {
          from: 'contacts',
          localField: 'leadDoc.contact',
          foreignField: '_id',
          as: 'leadContact',
        },
      },
      {
        $unwind: {
          path: '$leadContact',
          preserveNullAndEmptyArrays: true,
        },
      },

      {
        $addFields: {
          contact: {
            $ifNull: ['$directContact', '$leadContact'],
          },
        },
      },

      ...[
        { from: 'users', localField: 'assignedTo', as: 'assignedUser' },
        { from: 'users', localField: 'createdBy', as: 'createdByUser' },
      ].flatMap(({ from, localField, as }) => [
        {
          $lookup: { from, localField, foreignField: '_id', as },
        },
        {
          $unwind: { path: `$${as}`, preserveNullAndEmptyArrays: true },
        },
      ]),
      {
        $addFields: {
          'leadDoc.projectObjectId': {
            $cond: {
              if: { $ne: ['$leadDoc.project', null] },
              then: { $toObjectId: { $toString: '$leadDoc.project' } },
              else: null,
            },
          },
          'leadDoc.unitObjectId': {
            $cond: {
              if: { $ne: ['$leadDoc.unit', null] },
              then: { $toObjectId: { $toString: '$leadDoc.unit' } },
              else: null,
            },
          },
        },
      },
      {
        $lookup: {
          from: 'projects',
          localField: 'leadDoc.projectObjectId',
          foreignField: '_id',
          as: 'projectDoc',
        },
      },
      { $unwind: { path: '$projectDoc', preserveNullAndEmptyArrays: true } },
      {
        $lookup: {
          from: 'units',
          localField: 'leadDoc.unitObjectId',
          foreignField: '_id',
          as: 'unitDoc',
        },
      },
      { $unwind: { path: '$unitDoc', preserveNullAndEmptyArrays: true } },
      {
        $lookup: {
          from: 'sources',
          localField: 'leadDoc.source',
          foreignField: '_id',
          as: 'contactSourceDoc',
        },
      },
      {
        $unwind: {
          path: '$contactSourceDoc',
          preserveNullAndEmptyArrays: true,
        },
      },
      {
        $addFields: {
          'contact.source': {
            id: '$contactSourceDoc._id',
            name: '$contactSourceDoc.name',
          },
        },
      },
      {
        $lookup: {
          from: 'configurations',
          localField: 'leadDoc.configuration',
          foreignField: '_id',
          as: 'configurationDoc',
        },
      },
      {
        $lookup: {
          from: 'localities',
          localField: 'leadDoc.preferredLocalities',
          foreignField: '_id',
          as: 'localityDoc',
        },
      },
    ];

    if (search && search.trim()) {
      const term = escapeRegex(search.trim());
      const parts = term.split(/\s+/);

      if (parts.length === 1) {
        pipeline.push({
          $match: {
            $or: [
              { 'contact.firstName': { $regex: parts[0], $options: 'i' } },
              { 'contact.lastName': { $regex: parts[0], $options: 'i' } },
            ],
          },
        });
      } else {
        const regexStr = parts.join('.*');
        pipeline.push({
          $match: {
            $expr: {
              $regexMatch: {
                input: {
                  $concat: ['$contact.firstName', ' ', '$contact.lastName'],
                },
                regex: regexStr,
                options: 'i',
              },
            },
          },
        });
      }
    }

    if (activityDate)
      pipeline.push({
        $match: {
          $expr: {
            $eq: [
              { $dateToString: { format: '%d-%m-%Y', date: '$activityDate' } },
              activityDate,
            ],
          },
        },
      });

    if (dueDateFrom || dueDateTo) {
      const dateFilter: any = {};
      if (dueDateFrom) dateFilter.$gte = new Date(dueDateFrom);
      if (dueDateTo) dateFilter.$lte = new Date(dueDateTo);
      pipeline.push({
        $match: {
          activityDate: dateFilter,
        },
      });
    }

    pipeline.push({
      $project: {
        _id: 1,
        activityType: 1,
        activityDate: 1,
        notes: 1,
        callStatus: 1,
        location: 1,
        activityName: 1,
        status: 1,
        companyId: 1,

        'contact.id': '$contact._id',
        'contact.firstName': '$contact.firstName',
        'contact.lastName': '$contact.lastName',
        'contact.phone': '$contact.phone',
        'contact.source.id': '$contact.source.id',
        'contact.source.name': '$contact.source.name',

        'assignedUser.id': '$assignedUser._id',
        'assignedUser.firstName': '$assignedUser.firstName',
        'assignedUser.lastName': '$assignedUser.lastName',
        'createdByUser.id': '$createdByUser._id',
        'createdByUser.firstName': '$createdByUser.firstName',
        'createdByUser.lastName': '$createdByUser.lastName',

        'project.id': '$projectDoc._id',
        'project.projectName': '$projectDoc.projectName',

        'unit.id': '$unitDoc._id',
        'unit.unitNumber': '$unitDoc.unitNumber',

        configuration: '$configurationDoc.name',

        locality: '$localityDoc.name',

        leadScore: '$leadDoc.leadScore',
        leadId: 1,
        contactId: 1,
        createdAt: 1,
        updatedAt: 1,
      },
    });

    return Tasks.paginate({}, { ...options, aggregation: pipeline });
  } catch (_error) {
    throw new ApiError(
      defaultStatus.INTERNAL_SERVER_ERROR,
      'Failed to fetch tasks',
      true,
      '',
      TasksResponseCodes.TASKS_ERROR,
    );
  }
};
