import { trackEvent } from "./base"

import type { SelectedAncillary } from "@/types/components/myPages/myStay/ancillaries"
import { BreakfastPackageEnum } from "@/types/enums/breakfast"
import { CurrencyEnum } from "@/types/enums/currency"
import type { Room } from "@/types/stores/my-stay"
import type { PackageSchema } from "@/types/trpc/routers/booking/confirmation"
import type { CreditCard } from "@/types/user"
import type { BreakfastData } from "@/stores/my-stay/add-ancillary-flow"

export function trackCancelStay(hotelId: string, bnr: string) {
  trackEvent({
    event: "BookingCancellations",
    hotelInfo: {
      hotelId: hotelId,
      bnr: bnr,
    },
  })
}

export function trackMyStayPageLink(ctaName: string) {
  trackEvent({
    event: "confirmationPageLinks",
    cta: {
      name: ctaName,
    },
  })
}

type LateArrivalGuarantee = "mandatory" | "yes" | "no" | "na"

export function trackGlaSaveCardAttempt(
  hotelId: string,
  savedCreditCard: CreditCard | undefined,
  lateArrivalGuarantee: LateArrivalGuarantee
) {
  trackEvent({
    event: "glaCardSaveAttempt",
    hotelInfo: {
      hotelId,
      lateArrivalGuarantee,
      guaranteedProduct: "room",
    },
    paymentInfo: {
      status: "glacardsaveattempt",
      type: savedCreditCard?.cardType,
    },
  })
}

export function buildAncillariesTracking(
  packages: {
    code: string
    quantity: number
    comment?: string
  }[],
  selectedAncillary: SelectedAncillary | null | undefined,
  deliveryTime: string | string[] | null | undefined
) {
  return packages.map((pkg) => {
    const payedWithCard = pkg.code === selectedAncillary?.id
    const payedWithPoints = pkg.code === selectedAncillary?.loyaltyCode
    const ancillaryDeliveryTime = selectedAncillary?.requiresDeliveryTime
      ? deliveryTime
      : undefined

    return {
      productId: pkg.code,
      productUnits: pkg.quantity,
      productDeliveryTime: ancillaryDeliveryTime,
      productName: selectedAncillary?.title,
      productCategory: selectedAncillary?.categoryName,
      ...(payedWithCard && {
        productPrice: (selectedAncillary?.price.total ?? 0) * pkg.quantity,
        currency: selectedAncillary?.price.currency,
      }),
      ...(payedWithPoints && {
        productPoints: (selectedAncillary?.points ?? 0) * pkg.quantity,
      }),
    }
  })
}

export function trackGlaAncillaryAttempt(
  savedCreditCard: CreditCard | undefined,
  packages: {
    code: string
    quantity: number
    comment: string | undefined
  }[],
  selectedAncillary: SelectedAncillary | null,
  deliveryTime: string | undefined,
  breakfastData: BreakfastData | null
) {
  trackEvent({
    event: "GuaranteeAttemptAncillary",
    paymentInfo: {
      status: "glacardsaveattempt",
      type: savedCreditCard?.cardType,
    },
    ancillaries: breakfastData
      ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
      : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
    hotelInfo: {
      hotelId: selectedAncillary?.hotelId,
      lateArrivalGuarantee: "yes",
      guaranteedProduct: "room + ancillary",
    },
  })
}

export function trackAncillarySuccess(
  confirmationNumber: string,
  packages: {
    code: string
    quantity: number
    comment?: string
  }[],
  deliveryTime: string | null | undefined,
  guaranteedProduct: string,
  selectedAncillary: SelectedAncillary | null,
  breakfastData: BreakfastData | null,
  cardType?: string,
  roomTypeCode?: string
) {
  trackEvent({
    event: "AncillarySuccess",
    hotelInfo: {
      bnr: confirmationNumber,
      roomTypeCode: roomTypeCode,
      lateArrivalGuarantee: "yes",
      guaranteedProduct: guaranteedProduct,
    },
    paymentInfo: {
      status: "glacardsaveconfirmed",
      type: cardType,
    },
    ancillaries: breakfastData
      ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
      : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
  })
}

export function trackAncillaryFailed(
  packages: {
    code: string
    quantity: number
    comment?: string
  }[],
  deliveryTime: string | null | undefined,
  selectedAncillary: SelectedAncillary | null,
  breakfastData: BreakfastData | null
) {
  trackEvent({
    event: "GuaranteeFailAncillary",
    ancillaries: breakfastData
      ? buildBreakfastTracking(breakfastData, selectedAncillary?.hotelId)
      : buildAncillariesTracking(packages, selectedAncillary, deliveryTime),
    hotelInfo: {
      hotelId: selectedAncillary?.hotelId,
      lateArrivalGuarantee: "yes",
      guaranteedProduct: "ancillary",
    },
  })
}

export function buildBreakfastTracking(
  breakfastData: BreakfastData,
  hotelId?: number
) {
  const items = []

  if (breakfastData.nrOfAdults) {
    items.push({
      hotelId,
      productId: BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST,
      productName: "Breakfast",
      productUnits: breakfastData.nrOfAdults * breakfastData.nrOfNights,
      productPrice:
        breakfastData.priceAdult *
        breakfastData.nrOfAdults *
        breakfastData.nrOfNights,
      currency: breakfastData.currency,
      productCategory: "Food",
    })
  }

  if (breakfastData.nrOfPayingChildren) {
    items.push({
      hotelId,
      productId: BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST,
      productName: "Breakfast",
      productUnits: breakfastData.nrOfPayingChildren * breakfastData.nrOfNights,
      productPrice:
        breakfastData.priceChild *
        breakfastData.nrOfPayingChildren *
        breakfastData.nrOfNights,
      currency: breakfastData.currency,
      productCategory: "Food",
    })
  }

  return items
}

export function trackViewAncillary(
  ancillary: SelectedAncillary,
  booking: Room
) {
  const { hotelId, id, title, categoryName } = ancillary
  const isBreakfast = id === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
  const hasPayingChildren = booking.childrenAges.some((age) => age >= 4)

  const ancillaries = [
    {
      hotelId,
      productId: id,
      productName: title,
      productCategory: categoryName,
    },
  ]

  if (isBreakfast && hasPayingChildren) {
    ancillaries.push({
      hotelId,
      productId: BreakfastPackageEnum.ANCILLARY_CHILD_PAYING_BREAKFAST,
      productName: title,
      productCategory: categoryName,
    })
  }

  trackEvent({
    event: "viewAncillary",
    ancillaries,
  })
}

export function trackRemoveAncillary(
  ancillary: PackageSchema,
  hotelId: string,
  deliveryTime?: string,
  addedBreakfastPackages?: PackageSchema[]
) {
  const isBreakfastPackage =
    ancillary.code === BreakfastPackageEnum.ANCILLARY_REGULAR_BREAKFAST
  const isPoints = ancillary.currency === CurrencyEnum.POINTS
  const packagesWithoutFreeChildBreakfast = addedBreakfastPackages?.filter(
    (p) => p.code !== BreakfastPackageEnum.FREE_CHILD_BREAKFAST
  )

  const ancillaries = isBreakfastPackage
    ? (packagesWithoutFreeChildBreakfast?.map((pkg) => ({
        hotelId,
        productId: pkg.code,
        productPrice: pkg.totalPrice,
        productUnits: pkg.totalUnit,
        productType: pkg.type,
      })) ?? [])
    : [
        {
          hotelId,
          productId: ancillary.code,
          productPrice: isPoints ? 0 : ancillary.totalPrice,
          productPoints: isPoints ? ancillary.totalPrice : 0,
          productUnits: ancillary.totalUnit,
          productType: ancillary.type,
          productDeliveryTime: deliveryTime,
        },
      ]

  trackEvent({
    event: "removeAncillary",
    ancillaries,
  })
}

export function trackAddAncillary(
  ancillary: SelectedAncillary | null,
  quantityWithCard: number | null,
  quantityWithPoints: number | null,
  breakfastData: BreakfastData | null
) {
  if (breakfastData) {
    return trackEvent({
      event: "addAncillary",
      ancillaries: buildBreakfastTracking(breakfastData, ancillary?.hotelId),
    })
  }

  const ancillaries = []
  if ((quantityWithCard ?? 0) > 0) {
    ancillaries.push({
      hotelId: ancillary?.hotelId,
      productId: ancillary?.id,
      productName: ancillary?.title,
      productUnits: quantityWithCard,
      productPrice: (ancillary?.price.total ?? 0) * (quantityWithCard ?? 0),
      currency: ancillary?.price.currency,
      productCategory: ancillary?.categoryName,
    })
  }

  if ((quantityWithPoints ?? 0) > 0) {
    ancillaries.push({
      hotelId: ancillary?.hotelId,
      productId: ancillary?.loyaltyCode,
      productName: ancillary?.title,
      productUnits: quantityWithPoints,
      productPoints: (ancillary?.points ?? 0) * (quantityWithPoints ?? 0),
      productCategory: ancillary?.categoryName,
    })
  }
  trackEvent({
    event: "addAncillary",
    ancillaries,
  })
}
