/* eslint-disable @typescript-eslint/no-explicit-any */
import { PipelineStage } from 'mongoose';

interface PartnerNetworkPipelineParams {
  search?: string;
  companyType?: string;
  matchStage: Record<string, unknown>;
}

export const buildDiscoverPipeline = ({
  search,
  companyType = 'broker',
  matchStage,
}: PartnerNetworkPipelineParams): PipelineStage[] => {
  if (search)
    matchStage.$or = [
      { firstName: { $regex: search, $options: 'i' } },
      { lastName: { $regex: search, $options: 'i' } },
    ];

  return [
    { $match: matchStage },

    {
      $lookup: {
        from: 'companies',
        localField: 'company.id',
        foreignField: '_id',
        as: 'companyInfo',
      },
    },
    { $unwind: { path: '$companyInfo', preserveNullAndEmptyArrays: false } },

    {
      $match: {
        'companyInfo.companyType': companyType,
      },
    },

    {
      $lookup: {
        from: 'areas',
        localField: 'companyInfo.area',
        foreignField: '_id',
        as: 'areaInfo',
      },
    },
    { $unwind: { path: '$areaInfo', preserveNullAndEmptyArrays: true } },

    {
      $lookup: {
        from: 'cities',
        localField: 'companyInfo.city',
        foreignField: '_id',
        as: 'cityInfo',
      },
    },
    { $unwind: { path: '$cityInfo', preserveNullAndEmptyArrays: true } },

    {
      $lookup: {
        from: 'states',
        localField: 'companyInfo.state',
        foreignField: '_id',
        as: 'stateInfo',
      },
    },
    { $unwind: { path: '$stateInfo', preserveNullAndEmptyArrays: true } },

    {
      $project: {
        userName: { $concat: ['$firstName', ' ', '$lastName'] },
        companyName: '$companyInfo.name',
        areaName: '$areaInfo.name',
        cityName: '$cityInfo.name',
        stateName: '$stateInfo.name',
      },
    },
  ];
};

export const buildPartnerNetworkPipeline = ({
  search,
  matchStage,
  currentUserId,
}: PartnerNetworkPipelineParams & {
  currentUserId: string;
}): PipelineStage[] => {
  if (search) matchStage.$or = [{ name: { $regex: search, $options: 'i' } }];

  const isPending = matchStage.status === 'pending';

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

    // ✅ Only include requests where currentUser is sender or receiver
    {
      $match: {
        $expr: {
          $or: [
            { $eq: ['$senderId', { $toObjectId: currentUserId }] },
            { $eq: ['$receiverId', { $toObjectId: currentUserId }] },
          ],
        },
      },
    },
  ];

  // Determine who is the other user
  pipeline.push({
    $addFields: {
      isSender: { $eq: ['$senderId', { $toObjectId: currentUserId }] },
      otherUserId: {
        $cond: {
          if: { $eq: ['$senderId', { $toObjectId: currentUserId }] },
          then: '$receiverId',
          else: '$senderId',
        },
      },
      ...(isPending && {
        request: {
          $cond: {
            if: { $eq: ['$senderId', { $toObjectId: currentUserId }] },
            then: 'sent',
            else: 'received',
          },
        },
      }),
    },
  });

  pipeline.push(
    {
      $lookup: {
        from: 'users',
        localField: 'otherUserId',
        foreignField: '_id',
        as: 'otherUser',
      },
    },
    { $unwind: { path: '$otherUser', preserveNullAndEmptyArrays: false } },
    {
      $lookup: {
        from: 'companies',
        localField: 'otherUser.company.id',
        foreignField: '_id',
        as: 'companyInfo',
      },
    },
    { $unwind: { path: '$companyInfo', preserveNullAndEmptyArrays: false } },
    { $unwind: { path: '$areaInfo', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'cities',
        localField: 'companyInfo.city',
        foreignField: '_id',
        as: 'cityInfo',
      },
    },
    { $unwind: { path: '$cityInfo', preserveNullAndEmptyArrays: true } },
    {
      $lookup: {
        from: 'states',
        localField: 'companyInfo.state',
        foreignField: '_id',
        as: 'stateInfo',
      },
    },
    { $unwind: { path: '$stateInfo', preserveNullAndEmptyArrays: true } },
  );

  pipeline.push({
    $project: {
      userName: {
        $concat: ['$otherUser.firstName', ' ', '$otherUser.lastName'],
      },
      joinedOn: '$otherUser.createdAt',
      companyName: '$companyInfo.name',
      areaName: '$areaInfo.name',
      cityName: '$cityInfo.name',
      stateName: '$stateInfo.name',
      about: {
        email: '$otherUser.email',
        contact: '$otherUser.phone',
      },
      status: 1,
      otherUserId: 1,
      ...(isPending && { request: 1 }),
    },
  });

  return pipeline;
};

export const computePotentialMatches = (
  otherUserProperties: any[],
  currentUserProperties: any[],
) => {
  // Initialize counters
  const matchCounts: Record<string, number> = {
    sell: 0,
    rent: 0,
    lease: 0,
    preLeased: 0,
  };

  const matchedMap = new Map<string, any>();

  for (const otherProp of otherUserProperties)
    for (const myProp of currentUserProperties) {
      const sameCity = myProp.city?.toString() === otherProp.city?.toString();
      const sameCategory =
        myProp.categoryName?.toString() === otherProp.categoryName?.toString();
      const sameListingType = myProp.listingType === otherProp.listingType;

      if (!sameCity || !sameCategory || !sameListingType) continue;

      const listingType = myProp.listingType;

      matchCounts[listingType]++;

      const idStr = otherProp._id.toString();
      if (!matchedMap.has(idStr))
        matchedMap.set(idStr, {
          id: idStr,
          title: otherProp.title,
          listingType: otherProp.listingType,
          city: otherProp.cityName,
          categoryName: otherProp.categoryName,
          createdBy: otherProp.createdBy,
          // Add more fields if needed
        });

      break; // Only count one match per pair
    }

  return {
    ...matchCounts,
    matchedProperties: Array.from(matchedMap.values()),
  };
};
