import { FilterQuery, Types } from 'mongoose';
import { IContact, QueryFilter } from '@/modules/contacts/contacts.interface';
import { calcChange } from '@/shared/utils/arithmeticOp';
import { getObjectId } from '@/shared/utils/commonHelper';

export const formatDescription = (change: number, timeframe: string) => {
  const symbol = change > 0 ? '+' : change < 0 ? '−' : '';
  return `${symbol}${Math.abs(change)}% from ${timeframe}`;
};

export const buildContactFilter = (rawFilter: QueryFilter): FilterQuery<IContact> => {
  const { search, company, companyId, ids, source, ...baseFilters } = rawFilter;

  const filter: FilterQuery<IContact> = { ...baseFilters };
  
  if (source && typeof source === 'string') {
    if (source.includes(',')) {
      filter.source = {
        $in: source.split(',').map((id) => getObjectId(id.trim())),
      };
    } else {
      filter.source = getObjectId(source);
    }
  }

  if (ids) {
    const idList = Array.isArray(ids) ? ids : [ids];
    const objectIds = idList
      .filter((id) => typeof id === 'string' && Types.ObjectId.isValid(id))
      .map((id) => new Types.ObjectId(id as string));
    if (objectIds.length > 0) filter._id = { $in: objectIds };
  }

  if (search && typeof search === 'string')
    filter.$or = [
      { firstName: { $regex: search, $options: 'i' } },
      { lastName: { $regex: search, $options: 'i' } },
      { email: { $regex: search, $options: 'i' } },
      { workPhoneNumber: { $regex: search, $options: 'i' } },
    ];

  if (company && typeof company === 'string')
    filter.companyName = { $regex: new RegExp(`^${company}$`, 'i') };

  if (companyId) filter.company = companyId;
  delete filter.companyId;

  return filter;
};

export const buildAggregationStats = async (
  Model,
  matchBase: Record<string, unknown>,
  dates: Record<string, Date>,
) => {
  const {
    thisMonthStart,
    lastMonthStart,
    lastMonthEnd,
    thisWeekStart,
    lastWeekStart,
    lastWeekEnd,
  } = dates;

  const aggregation = await Model.aggregate([
    { $match: matchBase },
    {
      $facet: {
        totalContacts: [{ $count: 'count' }],
        totalContactsLastMonth: [
          {
            $match: { createdAt: { $gte: lastMonthStart, $lte: lastMonthEnd } },
          },
          { $count: 'count' },
        ],
        newContactsThisMonth: [
          { $match: { createdAt: { $gte: thisMonthStart } } },
          { $count: 'count' },
        ],
        newContactsLastMonth: [
          {
            $match: { createdAt: { $gte: lastMonthStart, $lte: lastMonthEnd } },
          },
          { $count: 'count' },
        ],
        contactedThisWeek: [
          { $match: { createdAt: { $gte: thisWeekStart } } },
          { $count: 'count' },
        ],
        contactedLastWeek: [
          { $match: { createdAt: { $gte: lastWeekStart, $lte: lastWeekEnd } } },
          { $count: 'count' },
        ],
        potentialBuyers: [
          { $match: { isPotentialBuyer: true } },
          { $count: 'count' },
        ],
        potentialBuyersLastMonth: [
          {
            $match: {
              isPotentialBuyer: true,
              createdAt: { $gte: lastMonthStart, $lte: lastMonthEnd },
            },
          },
          { $count: 'count' },
        ],
      },
    },
  ]);

  const result = aggregation[0] || {};

  const totalContacts = result.totalContacts?.[0]?.count || 0;
  const totalContactsLastMonth = result.totalContactsLastMonth?.[0]?.count || 0;
  const newContacts = result.newContactsThisMonth?.[0]?.count || 0;
  const newContactsLast = result.newContactsLastMonth?.[0]?.count || 0;
  const contacted = result.contactedThisWeek?.[0]?.count || 0;
  const contactedLast = result.contactedLastWeek?.[0]?.count || 0;
  const potential = result.potentialBuyers?.[0]?.count || 0;
  const potentialLast = result.potentialBuyersLastMonth?.[0]?.count || 0;

  return [
    {
      title: 'Total Contacts',
      value: totalContacts,
      description: formatDescription(
        calcChange(totalContacts, totalContactsLastMonth).change,
        'last month',
      ),
      icon: 'users',
    },
    {
      title: 'New Contacts This Month',
      value: newContacts,
      description: formatDescription(
        calcChange(newContacts, newContactsLast).change,
        'last month',
      ),
      icon: 'user-plus',
    },
    {
      title: 'Contacts Contacted This Week',
      value: contacted,
      description: formatDescription(
        calcChange(contacted, contactedLast).change,
        'last week',
      ),
      icon: 'user-check',
    },
    {
      title: 'Potential Buyers',
      value: potential,
      description: formatDescription(
        calcChange(potential, potentialLast).change,
        'last month',
      ),
      icon: 'home',
    },
  ];
};
