import { PipelineStage, Types } from 'mongoose';
import { TaskActivityType, TaskStatus } from '@/modules/tasks/tasks.constant';

export type TeamActivityReportView = 'overview' | 'detail' | 'all';

export const buildTeamActivityEnrichedPipeline = ({
  company,
  taskMatch,
  isBrokerCompany,
  selectedEntityIds,
  entityMatchField,
  leadStageIds,
  sourceIds,
  searchRegex,
}: {
  company: Types.ObjectId;
  taskMatch: Record<string, unknown>;
  isBrokerCompany: boolean;
  selectedEntityIds: Types.ObjectId[];
  entityMatchField: 'effectivePropertyId' | 'effectiveProjectId';
  leadStageIds: Types.ObjectId[];
  sourceIds: Types.ObjectId[];
  searchRegex: RegExp | null;
}): PipelineStage[] => {
  const enrichedPipeline: PipelineStage[] = [
    { $match: taskMatch },
    {
      $lookup: {
        from: 'users',
        localField: 'assignedTo',
        foreignField: '_id',
        as: 'assignedUserDoc',
      },
    },
    { $unwind: { path: '$assignedUserDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'leads',
        localField: 'leadId',
        foreignField: '_id',
        as: 'leadDoc',
      },
    },
    { $unwind: { path: '$leadDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'leadstages',
        localField: 'leadDoc.leadStage',
        foreignField: '_id',
        as: 'leadStageDoc',
      },
    },
    { $unwind: { path: '$leadStageDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'sources',
        localField: 'leadDoc.source',
        foreignField: '_id',
        as: 'sourceDoc',
      },
    },
    { $unwind: { path: '$sourceDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'contacts',
        localField: 'contactId',
        foreignField: '_id',
        as: 'taskContactDoc',
      },
    },
    { $unwind: { path: '$taskContactDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'contacts',
        localField: 'leadDoc.contact',
        foreignField: '_id',
        as: 'leadContactDoc',
      },
    },
    { $unwind: { path: '$leadContactDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'projects',
        localField: 'project',
        foreignField: '_id',
        as: 'taskProjectDoc',
      },
    },
    { $unwind: { path: '$taskProjectDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'projects',
        localField: 'leadDoc.project',
        foreignField: '_id',
        as: 'leadProjectDoc',
      },
    },
    { $unwind: { path: '$leadProjectDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'individualproperties',
        localField: 'property',
        foreignField: '_id',
        as: 'taskPropertyDoc',
      },
    },
    { $unwind: { path: '$taskPropertyDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'individualproperties',
        localField: 'leadDoc.property',
        foreignField: '_id',
        as: 'leadPropertyDoc',
      },
    },
    { $unwind: { path: '$leadPropertyDoc', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'unitbookingorholds',
        let: { currentLeadId: '$leadId' },
        pipeline: [
          {
            $match: {
              $expr: {
                $and: [
                  { $eq: ['$lead', '$$currentLeadId'] },
                  { $in: ['$action', ['book', 'hold']] },
                ],
              },
            },
          },
          { $sort: { createdAt: -1 } },
          { $limit: 1 },
          { $project: { project: 1, property: 1 } },
        ],
        as: 'latestLeadBookingDoc',
      },
    },
    {
      $unwind: {
        path: '$latestLeadBookingDoc',
        preserveNullAndEmptyArrays: true,
      },
    },
    {
      $lookup: {
        from: 'projects',
        localField: 'latestLeadBookingDoc.project',
        foreignField: '_id',
        as: 'bookingProjectDoc',
      },
    },
    {
      $unwind: { path: '$bookingProjectDoc', preserveNullAndEmptyArrays: true },
    },
    {
      $lookup: {
        from: 'individualproperties',
        localField: 'latestLeadBookingDoc.property',
        foreignField: '_id',
        as: 'bookingPropertyDoc',
      },
    },
    {
      $unwind: {
        path: '$bookingPropertyDoc',
        preserveNullAndEmptyArrays: true,
      },
    },
    {
      $lookup: {
        from: 'tasks',
        let: {
          currentLeadId: '$leadId',
          currentDate: '$activityDate',
          currentTaskId: '$_id',
        },
        pipeline: [
          {
            $match: {
              $expr: {
                $and: [
                  { $eq: ['$companyId', company] },
                  { $eq: ['$leadId', '$$currentLeadId'] },
                  { $eq: ['$status', TaskStatus.PENDING] },
                  { $gt: ['$activityDate', '$$currentDate'] },
                  { $ne: ['$_id', '$$currentTaskId'] },
                ],
              },
            },
          },
          { $sort: { activityDate: 1 } },
          { $limit: 1 },
          { $project: { activityDate: 1, activityType: 1 } },
        ],
        as: 'nextTaskDoc',
      },
    },
    {
      $addFields: {
        teamMemberName: {
          $trim: {
            input: {
              $concat: [
                { $ifNull: ['$assignedUserDoc.firstName', ''] },
                ' ',
                { $ifNull: ['$assignedUserDoc.lastName', ''] },
              ],
            },
          },
        },
        leadName: {
          $ifNull: [
            '$leadDoc.contactDetails.name',
            {
              $ifNull: [
                {
                  $trim: {
                    input: {
                      $concat: [
                        { $ifNull: ['$leadContactDoc.firstName', ''] },
                        ' ',
                        { $ifNull: ['$leadContactDoc.lastName', ''] },
                      ],
                    },
                  },
                },
                {
                  $trim: {
                    input: {
                      $concat: [
                        { $ifNull: ['$taskContactDoc.firstName', ''] },
                        ' ',
                        { $ifNull: ['$taskContactDoc.lastName', ''] },
                      ],
                    },
                  },
                },
              ],
            },
          ],
        },
        leadPrimaryPhoneFromDetails: {
          $let: {
            vars: { phoneValue: '$leadDoc.contactDetails.phone' },
            in: {
              $cond: [
                { $isArray: '$$phoneValue' },
                { $arrayElemAt: ['$$phoneValue', 0] },
                '$$phoneValue',
              ],
            },
          },
        },
        leadPrimaryPhone: {
          $ifNull: [
            '$leadPrimaryPhoneFromDetails',
            {
              $let: {
                vars: { phoneValue: '$leadContactDoc.phone' },
                in: {
                  $cond: [
                    { $isArray: '$$phoneValue' },
                    { $arrayElemAt: ['$$phoneValue', 0] },
                    '$$phoneValue',
                  ],
                },
              },
            },
          ],
        },
        taskPrimaryPhone: {
          $let: {
            vars: { phoneValue: '$taskContactDoc.phone' },
            in: {
              $cond: [
                { $isArray: '$$phoneValue' },
                { $arrayElemAt: ['$$phoneValue', 0] },
                '$$phoneValue',
              ],
            },
          },
        },
        phoneObject: { $ifNull: ['$leadPrimaryPhone', '$taskPrimaryPhone'] },
        entityName: {
          $cond: [
            isBrokerCompany,
            {
              $ifNull: [
                '$taskPropertyDoc.title',
                {
                  $ifNull: [
                    '$leadPropertyDoc.title',
                    {
                      $ifNull: [
                        '$bookingPropertyDoc.title',
                        {
                          $ifNull: [
                            '$taskProjectDoc.projectName',
                            {
                              $ifNull: [
                                '$leadProjectDoc.projectName',
                                '$bookingProjectDoc.projectName',
                              ],
                            },
                          ],
                        },
                      ],
                    },
                  ],
                },
              ],
            },
            {
              $ifNull: [
                '$taskProjectDoc.projectName',
                {
                  $ifNull: [
                    '$leadProjectDoc.projectName',
                    {
                      $ifNull: [
                        '$bookingProjectDoc.projectName',
                        {
                          $ifNull: [
                            '$taskPropertyDoc.title',
                            {
                              $ifNull: [
                                '$leadPropertyDoc.title',
                                '$bookingPropertyDoc.title',
                              ],
                            },
                          ],
                        },
                      ],
                    },
                  ],
                },
              ],
            },
          ],
        },
        leadStageName: { $ifNull: ['$leadStageDoc.stageName', 'Unknown'] },
        leadSourceName: { $ifNull: ['$sourceDoc.name', 'Unknown'] },
        effectiveProjectId: {
          $ifNull: [
            '$project',
            { $ifNull: ['$leadDoc.project', '$latestLeadBookingDoc.project'] },
          ],
        },
        effectivePropertyId: {
          $ifNull: [
            '$property',
            {
              $ifNull: ['$leadDoc.property', '$latestLeadBookingDoc.property'],
            },
          ],
        },
        nextTask: { $arrayElemAt: ['$nextTaskDoc', 0] },
        activityTypeLabel: {
          $switch: {
            branches: [
              {
                case: { $eq: ['$activityType', TaskActivityType.CALL] },
                then: 'Call',
              },
              {
                case: { $eq: ['$activityType', TaskActivityType.MEETING] },
                then: 'Meeting',
              },
              {
                case: { $eq: ['$activityType', TaskActivityType.SITE_VISIT] },
                then: 'Site Visit',
              },
              {
                case: { $eq: ['$activityType', TaskActivityType.OTHER] },
                then: 'Other',
              },
            ],
            default: 'Other',
          },
        },
        activityStatusLabel: {
          $switch: {
            branches: [
              {
                case: { $eq: ['$status', TaskStatus.COMPLETED] },
                then: 'Completed',
              },
              {
                case: { $eq: ['$status', TaskStatus.PENDING] },
                then: 'Pending',
              },
              {
                case: { $eq: ['$status', TaskStatus.OVERDUE] },
                then: 'Overdue',
              },
              {
                case: { $eq: ['$status', TaskStatus.CANCELLED] },
                then: 'Cancelled',
              },
            ],
            default: 'Pending',
          },
        },
      },
    },
    {
      $addFields: {
        contactNumber: {
          $let: {
            vars: {
              phoneType: { $type: '$phoneObject' },
              phoneValue: '$phoneObject',
              countryCode: '$phoneObject.countryCode',
              number: '$phoneObject.number',
            },
            in: {
              $cond: [
                { $ifNull: ['$$number', false] },
                {
                  $concat: [
                    {
                      $cond: [
                        { $ifNull: ['$$countryCode', false] },
                        { $concat: ['+', { $toString: '$$countryCode' }, ' '] },
                        '',
                      ],
                    },
                    { $toString: '$$number' },
                  ],
                },
                {
                  $cond: [
                    {
                      $in: [
                        '$$phoneType',
                        ['string', 'int', 'long', 'double', 'decimal'],
                      ],
                    },
                    { $toString: '$$phoneValue' },
                    '-',
                  ],
                },
              ],
            },
          },
        },
        nextActivityDate: '$nextTask.activityDate',
        nextActivityTypeLabel: {
          $switch: {
            branches: [
              {
                case: {
                  $eq: ['$nextTask.activityType', TaskActivityType.CALL],
                },
                then: 'Call',
              },
              {
                case: {
                  $eq: ['$nextTask.activityType', TaskActivityType.MEETING],
                },
                then: 'Meeting',
              },
              {
                case: {
                  $eq: ['$nextTask.activityType', TaskActivityType.SITE_VISIT],
                },
                then: 'Site Visit',
              },
              {
                case: {
                  $eq: ['$nextTask.activityType', TaskActivityType.OTHER],
                },
                then: 'Other',
              },
            ],
            default: null,
          },
        },
      },
    },
  ];

  if (selectedEntityIds.length > 0)
    enrichedPipeline.push({
      $match: {
        [entityMatchField]:
          selectedEntityIds.length === 1
            ? selectedEntityIds[0]
            : { $in: selectedEntityIds },
      },
    });

  if (leadStageIds.length > 0)
    enrichedPipeline.push({
      $match: {
        'leadDoc.leadStage':
          leadStageIds.length === 1 ? leadStageIds[0] : { $in: leadStageIds },
      },
    });

  if (sourceIds.length > 0)
    enrichedPipeline.push({
      $match: {
        'leadDoc.source':
          sourceIds.length === 1 ? sourceIds[0] : { $in: sourceIds },
      },
    });

  if (searchRegex)
    enrichedPipeline.push({
      $match: {
        $or: [
          { teamMemberName: searchRegex },
          { leadName: searchRegex },
          { contactNumber: searchRegex },
          { entityName: searchRegex },
          { leadStageName: searchRegex },
          { leadSourceName: searchRegex },
          { activityTypeLabel: searchRegex },
          { activityStatusLabel: searchRegex },
          { notes: searchRegex },
        ],
      },
    });

  return enrichedPipeline;
};

export const buildTeamActivityFacetStage = ({
  reportView,
  skip,
  limit,
}: {
  reportView: TeamActivityReportView;
  skip: number;
  limit: number;
}): Record<string, PipelineStage[]> => {
  const facetStage: Record<string, PipelineStage[]> = {};

  if (reportView !== 'detail') {
    facetStage.summary = [
      {
        $group: {
          _id: null,
          totalActivities: { $sum: 1 },
          completed: {
            $sum: {
              $cond: [{ $eq: ['$activityStatusLabel', 'Completed'] }, 1, 0],
            },
          },
          pending: {
            $sum: {
              $cond: [{ $eq: ['$activityStatusLabel', 'Pending'] }, 1, 0],
            },
          },
          overdue: {
            $sum: {
              $cond: [{ $eq: ['$activityStatusLabel', 'Overdue'] }, 1, 0],
            },
          },
          cancelled: {
            $sum: {
              $cond: [{ $eq: ['$activityStatusLabel', 'Cancelled'] }, 1, 0],
            },
          },
        },
      },
    ];

    facetStage.activityDistribution = [
      { $group: { _id: '$activityTypeLabel', count: { $sum: 1 } } },
      { $sort: { count: -1 } },
    ];

    facetStage.activityStatusByType = [
      {
        $group: {
          _id: {
            activityType: '$activityTypeLabel',
            status: '$activityStatusLabel',
          },
          count: { $sum: 1 },
        },
      },
    ];
  }

  if (reportView !== 'overview') {
    facetStage.tableData = [
      { $sort: { activityDate: -1 } },
      { $skip: skip },
      { $limit: limit },
      {
        $project: {
          id: { $toString: '$_id' },
          dateTime: '$activityDate',
          activityType: '$activityTypeLabel',
          teamMember: {
            $ifNull: [{ $ifNull: ['$teamMemberName', null] }, 'Unassigned'],
          },
          leadName: { $ifNull: ['$leadName', 'Unknown'] },
          contactNumber: { $ifNull: ['$contactNumber', '-'] },
          project: { $ifNull: ['$entityName', 'N/A'] },
          activityStatus: '$activityStatusLabel',
          leadStage: '$leadStageName',
          leadSource: '$leadSourceName',
          notes: { $ifNull: ['$notes', ''] },
          nextActivityDate: '$nextActivityDate',
          nextActivityType: '$nextActivityTypeLabel',
        },
      },
    ];

    facetStage.tableDataCount = [{ $count: 'totalResults' }];
  }

  return facetStage;
};
