import dayjs from 'dayjs';

import {
  NotificationStatus,
  UserType,
} from '@/modules/notification/notification.constant';
import { NotificationAppRedirect } from '@/modules/notification/notification.interface';
import { createNotification } from '@/modules/notification/notification.service';
import { formattedAmount, getObjectId } from '@/shared/utils/commonHelper';

// Helper to get location name and unit mention flag
const getLocationInfo = (unitBookingOrHold) => {
  const projectName = unitBookingOrHold.project?.projectName;
  const propertyName = unitBookingOrHold.property?.title;
  const locationName = propertyName || projectName || 'Unknown location';
  const mentionUnit = !propertyName;
  return { locationName, mentionUnit };
};

// Factory function returns title & description based on status
const getNotificationContent = (unitBookingOrHold, isExpired) => {
  const unitNo = unitBookingOrHold.unit?.unitNumber || 'Unknown unit';
  const { locationName, mentionUnit } = getLocationInfo(unitBookingOrHold);
  const updatedBy = unitBookingOrHold.updatedBy || unitBookingOrHold.createdBy;
  const actorName = updatedBy?.name || (updatedBy?.firstName
    ? `${updatedBy.firstName} ${updatedBy.lastName || ''}`.trim()
    : null) ||
    'Someone';
  const customerName =
    unitBookingOrHold.lead?.contactDetails?.name || 'a customer';
  const amountFormatted =
    unitBookingOrHold.bookingAmount !== undefined
      ? formattedAmount(unitBookingOrHold.bookingAmount)
      : 'an unknown amount';

  if (isExpired)
    return {
      title: 'Hold Expired',
      description: `Hold for Unit ${unitNo} in ${locationName} has expired. Update status if needed.`,
    };

  if (unitBookingOrHold.action === 'hold') {
    const holdUntilFormatted = unitBookingOrHold.holdUntil
      ? dayjs(unitBookingOrHold.holdUntil).format('D MMM YYYY')
      : 'an unknown date';

    return {
      title: 'Unit on Hold',
      description: mentionUnit
        ? `Unit ${unitNo} at ${locationName} has been held by ${actorName} until ${holdUntilFormatted}.`
        : `${locationName} has been held by ${actorName} until ${holdUntilFormatted}.`,
    };
  }

  if (unitBookingOrHold.action === 'book')
    return {
      title: 'Booking Confirmed',
      description: mentionUnit
        ? `Unit ${unitNo} in ${locationName} sold to ${customerName}. Booking amount ${amountFormatted}.`
        : `${locationName} sold to ${customerName}. Booking amount ${amountFormatted}.`,
    };

  return {
    title: 'Unit Notification',
    description: 'There is an update regarding your unit.',
  };
};

export const sendUnitFcmNotification = async (
  unitBookingOrHold,
  isExpired = false,
) => {
  const { title, description } = getNotificationContent(
    unitBookingOrHold,
    isExpired,
  );

  let appRedirect: NotificationAppRedirect = {
    screenType: 'Unit_Details',
  };

  if (unitBookingOrHold.project?._id && unitBookingOrHold.unit?._id) {
    appRedirect.id = unitBookingOrHold.project._id;
    appRedirect.unitId = unitBookingOrHold.unit._id;
    appRedirect.unitNumber = unitBookingOrHold.unit.unitNumber;
  } else if (unitBookingOrHold.property?._id) {
    appRedirect.id = unitBookingOrHold.property._id;
  }

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