[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/contexts/ActionsProviderV2.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React, { createContext, useContext, useReducer } from 'react'

import type {
  Address,
  ItemToAdd,
  ItemToRemove,
  ClientProfileData,
  CartSimulation,
  OfferingInput,
  Config,
  ProductItem,
  Runtime,
  ResponseValidateItem,
  IsClickToAddToCart,
  StoreTermsAndConditionsContent,
  ShowPaymentMethod,
  CounterSecond,
} from '../interfaces'

interface State {
  config?: Partial<Config> // TODO: This logic shouldn't be here
  onClickBehavior?: 'ensure-sku-selection'
  // url for Redirect Payments
  redirectUrl?: string
  // store runtime
  runtime: Runtime
  // Exito logic
  // Trigger for send event Clicks Button
  // TODO: Should exist another way to do this
  isClickAddToCart?: IsClickToAddToCart
  // This property is not being used
  isOpenModalViewUser: boolean
  // This property is not being used
  isMinimizeViewUser: boolean
  // determine if it is qa or prod
  sandbox?: boolean
  skuSelectorProps?: {
    visibleVariations?: string[]
    useImageInColor?: boolean
  }
  // This property is not being used
  isLoadingCvvField?: boolean
  // Preview Mode For the admin
  isPreview?: boolean
  // Add additional terms and conditions
  storeTermsAndConditionsContent?: StoreTermsAndConditionsContent[]
  showPaymentMethods: ShowPaymentMethod[]
  hideDiscount?: boolean
  addItemOffering?: (offeringInput: OfferingInput) => void
  addToCart: (item: ItemToAdd) => void
  cartSimulation: (simulationItems: CartSimulation) => Promise<Response>
  clearData: (items: ItemToRemove[]) => void
  handleGetDocumentsClient?: (email: string) => void
  handleSelectedItem?: (item: ProductItem) => void
  insertCoupon: (text: string) => void
  removeItemOffering?: (offeringInput: OfferingInput) => void
  updateItems: (items: ItemToRemove[]) => void
  updateOrderFormProfile: (profile: ClientProfileData) => void
  updateSelectedAddress: (address: Address) => void
  validateItems?: () => ResponseValidateItem[] | []
  secondAfterEmail?: CounterSecond
}

type Action =
  | {
      type: 'SET_ITEM'
      args: ItemToAdd
    }
  | {
      type: 'SET_SELECTED_ITEM'
      args: ProductItem
    }
  | {
      type: 'SET_REDIRECT_URL'
      args: string
    }
  | {
      type: 'SET_INITIAL_CONFIG'
      args: {
        config?: Partial<Config>
        hideDiscount?: boolean
        isPreview?: boolean
        showPaymentMethods?: ShowPaymentMethod[]
        skuSelectorProps?: {
          visibleVariations?: string[]
          useImageInColor?: boolean
        }
        storeTermsAndConditionsContent?: StoreTermsAndConditionsContent[]
        addItemOffering?: (offeringInput: OfferingInput) => void
        addToCart: (item: ItemToAdd) => void
        clearData: (items: ItemToRemove[]) => void
        handleGetDocumentsClient?: (email: string) => void
        handleSelectedItem: (item: ProductItem) => void
        insertCoupon?: (text: string) => void
        removeItemOffering?: (offeringInput: OfferingInput) => void
        updateItems: (items: ItemToRemove[]) => void
        updateOrderFormProfile: (profile: ClientProfileData) => void
        validateItems?: () => ResponseValidateItem[] | []
      }
    }
  // | {
  //     type: 'SET_VERSION'
  //     args: boolean
  //   }
  | {
      type: 'SET_IS_CLICK_ADD_TO_CART'
      args: IsClickToAddToCart
    }
  | {
      type: 'SET_IS_OPEN_MODAL_VIEW_USER'
      args: boolean
    }
  | {
      type: 'SET_IS_MINIMIZE_VIEW_USER'
      args: boolean
    }
  | {
      type: 'SET_STORE_CONFIG'
      args: Partial<Config>
    }
  | {
      type: 'SET_IS_LOADING_CVV_FIELD'
      args: boolean
    }
  | {
      type: 'SET_SHOW_PAYMENT_METHODS'
      args: ShowPaymentMethod[]
    }
  | {
      type: 'SET_SECOND'
    }
  | {
      type: 'SET_SECOND_DIRECT'
      args: number
    }
  | {
      type: 'SET_RESTART'
    }
  | {
      type: 'SET_INTERVAL_SECOND'
      args: ReturnType<typeof setInterval>
    }

type Dispatch = (action: Action) => void

interface Props {
  children: JSX.Element[] | JSX.Element
  updateSelectedAddress: (address: Address) => void
  cartSimulation: (simulationItems: CartSimulation) => Promise<Response>
  runtime: Runtime
  sandbox?: boolean
  isPreview?: boolean
}

const defaultState: State = {
  config: null as Partial<Config>,
  hideDiscount: false,
  isClickAddToCart: { isClick: false, data: null },
  isLoadingCvvField: false,
  isMinimizeViewUser: false,
  isOpenModalViewUser: false,
  isPreview: false,
  onClickBehavior: 'ensure-sku-selection',
  redirectUrl: '',
  runtime: null as Runtime,
  sandbox: false,
  showPaymentMethods: [] as ShowPaymentMethod[],
  storeTermsAndConditionsContent: [] as StoreTermsAndConditionsContent[],
  addItemOffering: () => {},
  addToCart: () => {},
  cartSimulation: null as () => Promise<Response>,
  clearData: () => {},
  handleGetDocumentsClient: () => {},
  handleSelectedItem: () => {},
  insertCoupon: () => {},
  removeItemOffering: () => {},
  updateItems: () => {},
  updateOrderFormProfile: () => {},
  updateSelectedAddress: () => {},
  validateItems: () => [],
  secondAfterEmail: {
    second: 60,
    intervalSetSecond: null,
  },
}

const reducer = (state: State, action: Action) => {
  switch (action.type) {
    case 'SET_ITEM': {
      const { args } = action

      return {
        ...state,
        itemToAdd: args,
      }
    }

    case 'SET_SELECTED_ITEM': {
      const { args } = action

      return {
        ...state,
        selectedItem: args,
      }
    }

    case 'SET_REDIRECT_URL': {
      const { args } = action

      return {
        ...state,
        redirectUrl: args,
      }
    }

    case 'SET_INITIAL_CONFIG': {
      const { args } = action

      return {
        ...state,
        config: args.config,
        hideDiscount: args.hideDiscount,
        isPreview: args?.isPreview,
        showPaymentMethods: args.showPaymentMethods,
        skuSelectorProps: args?.skuSelectorProps,
        storeTermsAndConditionsContent: args.storeTermsAndConditionsContent,
        addItemOffering: args.addItemOffering,
        addToCart: args.addToCart,
        clearData: args.clearData,
        handleGetDocumentsClient: args.handleGetDocumentsClient,
        handleSelectedItem: args.handleSelectedItem,
        insertCoupon: args.insertCoupon,
        removeItemOffering: args.removeItemOffering,
        updateItems: args.updateItems,
        updateOrderFormProfile: args.updateOrderFormProfile,
        validateItems: args.validateItems,
      }
    }

    // case 'SET_VERSION': {
    //   const { args } = action

    //   return {
    //     ...state,
    //     settings: {
    //       ...state.settings,
    //       isLiteVersion: args,
    //     },
    //   }
    // }

    case 'SET_IS_CLICK_ADD_TO_CART': {
      const { args } = action

      return {
        ...state,
        isClickAddToCart: args,
      }
    }

    case 'SET_IS_OPEN_MODAL_VIEW_USER': {
      const { args } = action

      return {
        ...state,
        isOpenModalViewUser: args,
      }
    }

    case 'SET_IS_MINIMIZE_VIEW_USER': {
      const { args } = action

      return {
        ...state,
        isMinimizeViewUser: args,
      }
    }

    case 'SET_STORE_CONFIG': {
      const { args } = action

      return {
        ...state,
        config: args,
      }
    }

    case 'SET_IS_LOADING_CVV_FIELD': {
      const { args } = action

      return {
        ...state,
        isLoadingCvvField: args,
      }
    }

    case 'SET_SHOW_PAYMENT_METHODS': {
      const { args } = action

      return {
        ...state,
        showPaymentMethods: args,
      }
    }

    case 'SET_SECOND': {
      return {
        ...state,
        secondAfterEmail: {
          ...state.secondAfterEmail,
          second: (state.secondAfterEmail.second -= 1),
        },
      }
    }

    case 'SET_SECOND_DIRECT': {
      const { args } = action

      return {
        ...state,
        secondAfterEmail: {
          ...state.secondAfterEmail,
          second: args,
        },
      }
    }

    case 'SET_RESTART': {
      return {
        ...state,
        secondAfterEmail: {
          ...state.secondAfterEmail,
          second: 60,
        },
      }
    }

    case 'SET_INTERVAL_SECOND': {
      const { args } = action

      return {
        ...state,
        secondAfterEmail: {
          ...state.secondAfterEmail,
          intervalSetSecond: args,
        },
      }
    }

    default: {
      return state
    }
  }
}

const ActionsContext = createContext(defaultState)
const ActionsDispatchContext = createContext<Dispatch | null>(null)

const ActionsProvider = ({
  children,
  updateSelectedAddress,
  cartSimulation,
  runtime,
  sandbox,
  isPreview,
}: Props) => {
  const [state, dispatch] = useReducer(reducer, {
    ...defaultState,
    updateSelectedAddress,
    cartSimulation,
    runtime,
    sandbox,
    isPreview,
  })

  return (
    <ActionsContext.Provider value={state}>
      <ActionsDispatchContext.Provider value={dispatch}>
        {children}
      </ActionsDispatchContext.Provider>
    </ActionsContext.Provider>
  )
}

const useActions = () => {
  return useContext(ActionsContext)
}

const useActionsDispatch = (): Dispatch => {
  return useContext(ActionsDispatchContext)
}

export { ActionsProvider, useActions, useActionsDispatch }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/__test__/setupTests.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import Enzyme, { configure, shallow, mount, render } from 'enzyme'
import Adapter from 'enzyme-adapter-react-16'

configure({ adapter: new Adapter() })
export { shallow, mount, render }
export default Enzyme

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/theme_.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import vtexTheme from '../vtex-styles.module.css'
import kuikpayTheme from '../kuikpay-styles.module.css'
import genericTheme from '../generic-styles.module.css'

// Solo aplica esta validación para estilos globales
export const validateStyles = (theme: string) => {
  switch (theme) {
    case 'generic':
      return genericTheme

    case 'vtex':
      return vtexTheme

    case 'kuikpay':
      return kuikpayTheme

    default:
      return genericTheme
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/packages.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  ChangeLogistics,
  Sla,
  SlaSummary,
  PackageSummary,
} from '../interfaces'
import { formatter } from '.'
import type { LogisticInfo } from '../interfaces/orderForm'

interface PropsProcessInfo {
  logisticsInfo: LogisticInfo[]
  intl: any
  slas: SlaSummary
}
export const messages = {
  homeDelivery: {
    id: 'store/checkoutless.logistics.homeDelivery',
  },
  packageSteps: {
    id: 'store/checkoutless.logistics.packageSteps',
  },
  pickUpInStore: {
    id: 'store/checkoutless.logistics.pickUpInStore',
  },
  deliveryCost: {
    id: 'store/checkoutless.logistics.deliveryCost',
  },
  freeDeliveryCost: {
    id: 'store/checkoutless.logistics.freeDeliveryCost',
  },
}

export const processInfoPackages = ({
  logisticsInfo,
  intl,
  slas,
}: PropsProcessInfo) => {
  let step = ''
  let price = 0
  let friendlyName = ''
  let deliveryTypeName = ''

  const summaryChangeLogistics: ChangeLogistics[] = []

  const packages = [logisticsInfo[0]]

  logisticsInfo.forEach((logistic) => {
    const packageExist = packages.find(
      (info) =>
        info.selectedDeliveryChannel &&
        info.selectedSla === logistic.selectedSla
    )

    if (!packageExist) packages.push(logistic)
  })

  const packagesSummary: PackageSummary[] = packages.map((logistic, index) => {
    let day = ''
    let timeRange = ''
    let deliveryDate = ''
    let deliveryWindowPrice = 0
    const deliveryType = logistic?.selectedDeliveryChannel

    step = intl.formatMessage(messages.packageSteps, {
      step: index + 1,
      totalSteps: packages.length,
    })

    const actualSla = slas[deliveryType]?.find(
      (sla: Sla) => sla.id === logistic.selectedSla
    )

    price = actualSla?.price || 0

    if (deliveryType === 'delivery') {
      deliveryTypeName = intl.formatMessage(messages.homeDelivery)
      friendlyName = ''
    } else {
      deliveryTypeName = intl.formatMessage(messages.pickUpInStore)
      friendlyName = `${logistic?.storeName || 'tienda'}`
    }

    if (
      logistic?.deliveryWindow?.startDateUtc &&
      logistic?.deliveryWindow?.startDateUtc !== ''
    ) {
      const startDate = new Date(
        logistic?.deliveryWindow?.startDateUtc.split('+')[0]
      )

      const endDate = new Date(
        logistic?.deliveryWindow?.endDateUtc?.split('+')[0]
      )

      const fmtDay = new Intl.DateTimeFormat('es-CO', {
        weekday: 'long',
        day: '2-digit',
        month: 'short',
      })

      const fmtTime = new Intl.DateTimeFormat('es-CO', {
        hour12: true,
        hour: 'numeric',
        minute: 'numeric',
      })

      const slaDeliveryWindow = actualSla?.availableDeliveryWindows.find(
        (deliveryWindow: any) =>
          deliveryWindow.startDateUtc === logistic.deliveryWindow.startDateUtc
      )

      deliveryWindowPrice = slaDeliveryWindow?.price || 0
      deliveryWindowPrice /= 100

      day = `${fmtDay.format(startDate)}`
      timeRange = `${fmtTime.format(startDate)} - ${fmtTime.format(endDate)}`
      deliveryDate = `${day} | ${timeRange}`
    }

    const priceMessage = `${intl.formatMessage(messages.deliveryCost)} ${
      price + deliveryWindowPrice !== 0
        ? `(${formatter.format(price + deliveryWindowPrice)})`
        : `(${intl.formatMessage(messages.freeDeliveryCost)})`
    } `

    summaryChangeLogistics.push({
      shippingPackage: index + 1,
      selectedSla: logistic?.selectedSla,
      selectedDeliveryChannel: deliveryType,
      deliveryWindow: logistic?.deliveryWindow,
      scheduleDelivery: {
        day,
        timeRange,
      },
    })

    return {
      deliveryType,
      deliveryTypeName,
      selectedSla: logistic?.selectedSla,
      deliveryDate,
      step,
      price: priceMessage,
      storeInfo: friendlyName,
    }
  })

  return { summaryChangeLogistics, packagesSummary }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/constants.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
export default {
  JQUERY_SCRIPT: ['https://code.jquery.com/jquery-1.11.3.min.js', 'script'],
  PCI_PROXY_SCRIPT: [
    'https://pay.datatrans.com/upp/payment/js/secure-fields-2.0.0.js',
    'script',
  ],
  PCI_PROXY_SCRIPT_DEV: [
    'https://pay.sandbox.datatrans.com/upp/payment/js/secure-fields-2.0.0.js',
    'script',
  ],
  PAYMENTEZ_SCRIPT: [
    'https://cdn.paymentez.com/ccapi/sdk/payment_stable.min.js',
    'script',
  ],
  PAYMENTEZ_LINK: [
    'https://cdn.paymentez.com/ccapi/sdk/payment_stable.min.css',
    'link',
  ],
  PAYMENTEZ_CREDENTIALS: {
    stg: ['stg', '', ''],
    prod: ['prod', '', ''],
  },
  MERCADOPAGO_SCRIPT: ['https://sdk.mercadopago.com/js/v2', 'script'],
  salesChannel: '1',
  currencyCode: 'COP',
  countryCode: 'COL',
  lastStep: 5,
  prefix: '+57',
  documentType: 'CC',
  mercadoPagoPublicKey: '',
  gateway: 'Mercadopago',
  merchantID: '',
  merchantIDDev: '',
  serverErrorMessage:
    'A communication error occurred with the MyCheckout server',
  accountNotConfiguredMessage: 'Account is not setup yet',
  MYCHECKOUT_CSS: ['/arquivos/mycheckout.css', 'link'],
  ORDER_PLACED_LINK: `https://${window?.location?.hostname}/checkout/gatewayCallback/`,
}
export const KEYS_NOT_SET_TYPING = [
  'Tab',
  'ArrowRight',
  'ArrowDown',
  'ArrowUp',
  'ArrowLeft',
  'Meta',
  'Alt',
  'Control',
  'Shift',
  ' ',
  'CapsLock',
  'Backspace',
]
export const ENTER_EMAIL = 'EnterEmail'
export const PERSONAL_DATA = 'PersoanlData'
export const SHIPPING_DATA = 'ShippingData'
export const SHIPPING_TYPE_DATA = 'ShippingTypeData'
export const COUPON = 'Coupon'
export const PAYMENT = 'Payment'
export const BUY_COMPLETED = 'BuyCompleted'
export const COOKIE_NAME_GTM = 'checkoutless_gtm'
export const stepByName = {
  EnterEmail: 1,
  PersoanlData: 2,
  ShippingData: 3,
  ShippingTypeData: 4,
  Coupon: 5,
  Payment: 6,
  BuyCompleted: 7,
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/index.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
/* eslint-disable @typescript-eslint/no-explicit-any */

import type { StepsCookieGTM } from '../services/GoogleTagManager/InterfacesGTM'

/* eslint-disable max-params */
export const regularExpressions = {
  user: /^[a-zA-Z0-9_-]{4,16}$/, // Letras, numeros, guion y guion_bajo
  name: /^(?!\s)[a-zA-ZÀ-ÿ\s]{1,40}$/, // Letras y espacios, pueden llevar acentos.
  firstName: /^(?!\s)[a-zA-ZÀ-ÿ\s]{1,40}$/, // Letras y espacios, pueden llevar acentos.
  lastName: /^(?!\s)[a-zA-ZÀ-ÿ\s]{1,40}$/, // Letras y espacios, pueden llevar acentos.
  password: /^.{4,12}$/, // 4 a 12 digitos.
  email:
    /^[a-z0-9+_-]+(?:\.[a-z0-9+_-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/,
  phone: /^(^(\+)?\d{2})?\d{7}(\d{3})?$/, // 7 a 10 numeros con codigo de pais condicional.
  document: /^\d{1,10}$/, // 1 a 10 numeros.
  cardholderName: /^(?!\s)[a-zA-ZÀ-ÿ\s]{5,30}$/,
  cardNumber: /^[0-9\s]{19,19}$/,
  cardNumber2: /^[0-9\s]{16,22}$/,
  securityCode1: /^[0-9]{3,3}$/,
  securityCode2: /^[0-9]{4,4}$/,
  dues: /\d{2}/g,
  cvc: /\d{3,4}/g,
  expiryDate: /^\d{2}\/\d{2}/g,
  neighborhood: /^(?!\s)[^]+$/, // No vacio y que al comienzo no tenga un espacio
}

export const validateEmail = (email: string) => {
  const re = regularExpressions.email

  return re.test(String(email).toLowerCase())
}

export const formatter = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  minimumFractionDigits: 0,
  maximumFractionDigits: 0,
})

export const getCookie = (key: string) => {
  const b = document.cookie.match(`(^|;)\\s*${key}\\s*=\\s*([^;]+)`)

  return b ? b.pop() : ''
}

export const setCookie = (
  name: string,
  value: string | Record<string, unknown> | StepsCookieGTM,
  days: number = null
) => {
  if (typeof value !== 'string') value = JSON.stringify(value)
  let expires = ''

  if (days) {
    const date = new Date()

    date.setTime(date.getTime() + days * 24 * 60 * 60 * 1000)
    expires = `; expires=${date.toUTCString()}`
  }

  document.cookie = `${name}=${value || ''} ${expires}; path=/`
}

export const expireCookie = (key: string, secure = true) => {
  document.cookie = `${key}=; path=/; expires=Fri, 01 Apr 2022 15:31:07 GMT; domain=.${
    window.location.hostname
  }; ${secure ? 'secure' : ''}`
}

export const validateCrediCard = (
  cardNumber: string,
  cardType: string,
  name: string,
  expiryMonth: string,
  expiryYear: string,
  validateExpiryDate?: any
) => {
  console.warn(`cardType`, cardType)
  console.warn(`expiryMonth`, expiryMonth)
  console.warn(`expiryYear`, expiryYear)

  const cardholderNameValidate = regularExpressions.cardholderName.test(name)
  const cardNumberValidate = regularExpressions.cardNumber.test(cardNumber)
  const cardExpiration = validateExpiryDate

  return {
    invalidCardholderName: cardholderNameValidate,
    cardholderName: !!name,
    invalidCardNumber: !cardType ? false : cardNumberValidate,
    cardNumber: !!cardNumber,
    invalidCardExpiration: cardExpiration,
  }
}

export const isMobile = () => {
  return (
    navigator.userAgent.match(/Android/i) ||
    navigator.userAgent.match(/webOS/i) ||
    navigator.userAgent.match(/iPhone/i) ||
    navigator.userAgent.match(/iPod/i) ||
    navigator.userAgent.match(/iPad/i) ||
    navigator.userAgent.match(/BlackBerry/i)
  )
}

export const arrayEquals = (a: any, b: any) => {
  return (
    Array.isArray(a) &&
    Array.isArray(b) &&
    a.length === b.length &&
    a.every((val, index) => val === b[index])
  )
}

export const mergeArrays = (a: any, b: any, prop: string) => {
  const reduced = a.filter((aitem: any) => {
    return !b.find((bitem: any) => {
      return aitem[prop] === bitem[prop]
    })
  })

  return reduced.concat(b)
}

export const removeAccents = (str: string | null) => {
  return str?.normalize('NFD').replace(/[\u0300-\u036f]/g, '')
}

export const emptyFunction = () => {}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/dataMapper.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  AddressMC,
  PaymentsMC,
  ProfileMC,
  ShippingMC,
} from '../interfaces/orderForm'

export const userInfoMapper = (
  userData: any,
  addressAlternative?: AddressMC
): {
  profile: ProfileMC
  shipping?: ShippingMC
  payments?: PaymentsMC
} => {
  const availableAddresses: AddressMC[] = userData.addresses?.map(
    (address: any): AddressMC => ({
      id: address.id,
      city: address.city,
      complement: address.reference,
      country: address.country,
      number: address.number,
      reference: address.reference,
      geoCoordinates: {
        latitude: address.geoCoordinates.latitude,
        longitude: address.geoCoordinates.longitude,
      },
      neighborhood: address.neighborhood,
      postalCode: address.postalCode,
      receiverName: address.receiverName,
      state: address.state,
      street: address.street,
      addressDeliveryType: 'delivery',
    })
  )

  const addressAlternativeWhitPostalCode = availableAddresses?.find(
    (address: AddressMC) => address?.id === addressAlternative?.id
  )

  let newAddressAlternative: AddressMC = addressAlternative
    ? {
        id: addressAlternative?.id,
        city: addressAlternative?.city,
        complement: addressAlternative?.reference,
        country: addressAlternative?.country,
        geoCoordinates: {
          latitude: addressAlternative?.geoCoordinates?.latitude,
          longitude: addressAlternative?.geoCoordinates?.longitude,
        },
        neighborhood: addressAlternative?.neighborhood,
        postalCode: addressAlternative?.postalCode,
        receiverName: addressAlternative?.receiverName,
        state: addressAlternative?.state,
        street: addressAlternative?.street,
        number: addressAlternative?.number,
        reference: addressAlternative?.reference,
        addressDeliveryType: addressAlternative?.addressDeliveryType,
      }
    : null

  if (addressAlternative?.addressDeliveryType === 'delivery') {
    if (!addressAlternativeWhitPostalCode?.id) {
      availableAddresses.push(addressAlternative)
    } else {
      newAddressAlternative = addressAlternativeWhitPostalCode
    }
  }

  return {
    profile: {
      ...(userData.id ? { id: userData.id } : {}),
      ...(userData.habeasData === undefined
        ? {}
        : { habeasData: userData.habeasData }),
      email: userData.email,
      name: userData.name,
      lastname: userData.lastname,
      documentType: userData.id_type,
      document: userData.id_number,
      phoneCode: userData.phone_code,
      phone: userData.phone_number,
    },
    shipping: {
      availableAddresses,
      address:
        newAddressAlternative &&
        addressAlternative?.addressDeliveryType === 'delivery'
          ? { ...newAddressAlternative }
          : userData.selectedAddress && {
              id: userData.selectedAddress.id,
              city: userData.selectedAddress.city,
              complement: userData.selectedAddress.reference,
              country: userData.selectedAddress.country,
              geoCoordinates: {
                latitude: userData.selectedAddress.geoCoordinates.latitude,
                longitude: userData.selectedAddress.geoCoordinates.longitude,
              },
              neighborhood: userData.selectedAddress.neighborhood,
              postalCode: userData.selectedAddress.postalCode,
              receiverName: userData.selectedAddress.receiverName,
              state: userData.selectedAddress.state,
              street: userData.selectedAddress.street,
              number: userData.selectedAddress.number,
              reference: userData.selectedAddress.reference,
              addressDeliveryType: 'delivery',
            },
      selectedAddresses: [
        ...(userData.selectedAddress && !newAddressAlternative
          ? [
              {
                id: userData.selectedAddress.id,
                city: userData.selectedAddress.city,
                complement: userData.selectedAddress.reference,
                country: userData.selectedAddress.country,
                geoCoordinates: {
                  latitude: userData.selectedAddress.geoCoordinates.latitude,
                  longitude: userData.selectedAddress.geoCoordinates.longitude,
                },
                neighborhood: userData.selectedAddress.neighborhood,
                postalCode: userData.selectedAddress.postalCode,
                receiverName: userData.selectedAddress.receiverName,
                state: userData.selectedAddress.state,
                street: userData.selectedAddress.street,
                number: userData.selectedAddress.number,
                reference: userData.selectedAddress.reference,
                addressDeliveryType: 'delivery',
              } as AddressMC,
            ]
          : userData.selectedAddress &&
            newAddressAlternative &&
            addressAlternative?.addressDeliveryType === 'pickup' &&
            userData.selectedAddress.id !== newAddressAlternative.id
          ? [
              { ...newAddressAlternative },
              {
                id: userData.selectedAddress.id,
                city: userData.selectedAddress.city,
                complement: userData.selectedAddress.reference,
                country: userData.selectedAddress.country,
                geoCoordinates: {
                  latitude: userData.selectedAddress.geoCoordinates.latitude,
                  longitude: userData.selectedAddress.geoCoordinates.longitude,
                },
                neighborhood: userData.selectedAddress.neighborhood,
                postalCode: userData.selectedAddress.postalCode,
                receiverName: userData.selectedAddress.receiverName,
                state: userData.selectedAddress.state,
                street: userData.selectedAddress.street,
                number: userData.selectedAddress.number,
                reference: userData.selectedAddress.reference,
                addressDeliveryType: 'delivery',
              } as AddressMC,
            ]
          : newAddressAlternative
          ? [{ ...newAddressAlternative }]
          : []),
      ],
    },
    payments: {
      payment: [
        ...(userData.selectedPayment?.paymentMethod === 'tc'
          ? [
              {
                cardId: userData.selectedPayment?.card.id,
                bin: userData.selectedPayment?.card.bin,
                franchise: userData.selectedPayment?.card.franchise,
                number: userData.selectedPayment?.card.number,
                gateway: userData.selectedPayment?.card.gateway,
                paymentMethod: userData.selectedPayment?.paymentMethod,
                paymentId: userData.selectedPayment?.card.paymentSystem,
              },
            ]
          : userData.selectedPayment?.paymentMethod !== 'tc' &&
            userData.cards.length
          ? [
              {
                cardId: userData.cards[0]?.id,
                bin: userData.cards[0]?.bin,
                franchise: userData.cards[0]?.franchise,
                number: userData.cards[0]?.number,
                gateway: userData.cards[0]?.gateway,
                paymentMethod: 'tc',
                paymentId: userData.cards[0]?.paymentSystem,
              },
            ]
          : []),
      ],
      availableCards: [
        ...userData.cards?.map((card: any) => ({
          cardId: card.id,
          bin: card.bin,
          franchise: card.franchise,
          number: card.number,
          gateway: card.gateway,
        })),
      ],
      selectedCard:
        userData.selectedPayment?.card &&
        userData.selectedPayment?.paymentMethod === 'tc'
          ? {
              cardId: userData.selectedPayment?.card.id,
              bin: userData.selectedPayment?.card.bin,
              franchise: userData.selectedPayment?.card.franchise,
              number: userData.selectedPayment?.card.number,
              gateway: userData.selectedPayment?.card.gateway,
            }
          : userData.selectedPayment?.paymentMethod !== 'tc' &&
            userData.cards.length
          ? {
              cardId: userData.cards[0]?.id,
              bin: userData.cards[0]?.bin,
              franchise: userData.cards[0]?.franchise,
              number: userData.cards[0]?.number,
              gateway: userData.cards[0]?.gateway,
            }
          : null,
    },
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/payments.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { PaymentsMethod } from '../interfaces'

// reemplaza cualquier caracter que no es un numero por un vacío
export const clearNumber = (value = '') => {
  return value.replace(/\D+/g, '')
}

export const formatExpiryDate = (value: string) => {
  const clearValue = clearNumber(value)

  if (clearValue.length >= 3) {
    return `${clearValue.slice(0, 2)}/${clearValue.slice(2, 4)}`
  }

  return clearValue
}

export const selectIdImgCard = (paymentMethod: string) => {
  let dataImgCard = null
  // eslint-disable-next-line padding-line-between-statements
  if (
    paymentMethod === 'VIS' ||
    paymentMethod === 'vi' ||
    paymentMethod === 'visa' ||
    paymentMethod === 'Visa'
  ) {
    dataImgCard = { id: '155401', name: 'visa', nameComplete: 'visa' }
  } else if (
    paymentMethod === 'ECA' ||
    paymentMethod === 'mc' ||
    paymentMethod === 'master' ||
    paymentMethod === 'Master' ||
    paymentMethod === 'Mastercard'
  ) {
    dataImgCard = {
      id: '155402',
      name: 'mastercard',
      nameComplete: 'mastercard',
    }
  } else if (
    paymentMethod === 'AMX' ||
    paymentMethod === 'ae' ||
    paymentMethod === 'amex' ||
    paymentMethod === 'Amex' ||
    paymentMethod === 'American Express'
  ) {
    dataImgCard = {
      id: '155404',
      name: 'amex',
      nameComplete: 'american express',
    }
  } else if (
    paymentMethod === 'DIN' ||
    paymentMethod === 'di' ||
    paymentMethod === 'diner' ||
    paymentMethod === 'Diner' ||
    paymentMethod === 'Diners'
  ) {
    dataImgCard = { id: '155403', name: 'diners', nameComplete: 'diners' }
  }

  return dataImgCard
}

export const getImgFranchise = (fran: string) => {
  const franchise = fran?.toLowerCase()
  let idImgFranchise = ''

  if (franchise === 'vi' || franchise === 'visa') {
    idImgFranchise = '155401'
  } else if (
    franchise === 'di' ||
    franchise === 'diners' ||
    franchise === 'diner'
  ) {
    idImgFranchise = '155403'
  } else if (franchise === 'mc' || franchise === 'master') {
    idImgFranchise = '155402'
  } else if (franchise === 'ae' || franchise === 'amex') {
    idImgFranchise = '155404'
  }

  const url = `https://kuikpay.vteximg.com.br/arquivos/ids/${idImgFranchise}`

  return url
}

export const PaymentKey = {
  Orion: 'Orion',
}

export const validateOrion = (paymentMethod: PaymentsMethod[]) => {
  return !!paymentMethod.find(
    (payment) =>
      payment.paymentMethodName === PaymentKey.Orion && payment?.isActive
  )
}

export const copyAttributes = (
  from: string,
  toObj: any,
  exceptions: string[]
) => {
  $.each(
    $(from).prop('attributes'),
    (_: never, attr: { name: string; value: string }) => {
      if (!exceptions.includes(attr.name)) {
        toObj.attr(attr.name, attr.value)
      }
    }
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/utils/simulation.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  LogisticsInfo,
  Item,
  Sla,
  SlaSummary,
  Totalizer,
  Address,
  TotalizerId,
} from '../interfaces'
import type { ItemSimulation } from '../interfaces/simulation'

export const slasSummary = (logisticsInfo: LogisticsInfo[]): SlaSummary => {
  const slas =
    logisticsInfo
      ?.map((logistic: LogisticsInfo) =>
        logistic.slas?.map((sla, i) => {
          if (sla?.pickupStoreInfo?.address) {
            sla.pickupStoreInfo.address.addressType = 'search'
          }

          return {
            itemIndex: logistic.itemIndex,
            id: sla?.id,
            deliveryChannel: sla?.deliveryChannel,
            name: sla?.name,
            shippingEstimate: sla?.shippingEstimate,
            shippingEstimateDate: sla?.shippingEstimateDate,
            availableDeliveryWindows: sla?.availableDeliveryWindows,
            price: sla?.price,
            index: i,
            pickupStoreInfo: {
              additionalInfo: sla?.pickupStoreInfo?.additionalInfo,
              friendlyName: sla?.pickupStoreInfo?.friendlyName,
              address: sla?.pickupStoreInfo?.address,
            },
          }
        })
      )
      .reduce((acc, next) => acc.concat(next), []) || []

  const itemsIndex = logisticsInfo?.map(
    (logistic: LogisticsInfo) => logistic.itemIndex
  )

  const slasGroupById = {}

  for (const sla of slas) {
    const keys = Object.keys(slasGroupById)

    if (keys.includes(sla.id)) {
      slasGroupById[sla.id].push(sla)
    } else {
      slasGroupById[sla.id] = [sla]
    }
  }

  const consolidatedSlas = []
  const groupedKeys = Object.keys(slasGroupById)

  for (const key of groupedKeys) {
    const total = slasGroupById[key]
      .map((sla: Sla) => sla.price)
      .reduce((acc: number, next: number) => acc + next, 0)

    const consolidateitemsIndex = slasGroupById[key].map(
      (sla: Sla) => sla.itemIndex
    )

    const consolidatePrices = slasGroupById[key].map((sla: any) => {
      const index = sla.itemIndex

      return { [index]: sla.price }
    })

    const [consolidatedSla] = slasGroupById[key]

    consolidatedSla.price = total / 100
    consolidatedSla.itemIndex = consolidateitemsIndex
    consolidatedSla.prices = consolidatePrices
    consolidatedSlas.push(consolidatedSla)
  }

  const deliveryPoints = consolidatedSlas.filter(
    (sla) => sla.deliveryChannel === 'delivery'
  )

  deliveryPoints.sort((a, b) => {
    if (a.price > b.price) return 1
    if (a.price < b.price) return -1

    return 0
  })
  const pickupPoints = consolidatedSlas.filter(
    (sla) => sla.deliveryChannel === 'pickup-in-point'
  )

  pickupPoints.sort((a, b) => {
    if (a.price > b.price) return 1
    if (a.price < b.price) return -1

    return 0
  })

  return {
    delivery: deliveryPoints,
    'pickup-in-point': pickupPoints,
    itemsIndex,
  }
}

export const defaultPackages = (
  slaSummary: SlaSummary,
  simulationItems: any,
  addressAlter?: Address
) => {
  const defaultLogistics: LogisticsInfo[] = []
  let totalItems = slaSummary.itemsIndex
  let deliverySlas = slaSummary.delivery
  let pickupSlas = slaSummary['pickup-in-point']
  const itemsUsed: number[] = []

  const itemsAvailability = simulationItems.filter(
    (item: Item) => item.availability !== 'available'
  )

  if (itemsAvailability.length < 1) {
    do {
      if (
        deliverySlas.length > 0 &&
        (!addressAlter ||
          addressAlter?.addressType === 'residential' ||
          (addressAlter?.addressType === 'search' && pickupSlas.length === 0))
      ) {
        const [delivery] = deliverySlas
        let slaItems = delivery.itemIndex

        slaItems = slaItems.filter((item: number) => !itemsUsed.includes(item))
        slaItems.forEach((item) => itemsUsed.push(item))

        if (slaItems.length !== delivery.itemIndex.length) {
          const newPriceByItem = delivery.prices.filter((itemIndex) => {
            const item = parseInt(Object.keys(itemIndex)[0], 10)

            return slaItems.includes(item)
          })

          const usedPrices = newPriceByItem.map((price) => Object.values(price))
          const mergePrices = [].concat([], ...usedPrices)
          const total = mergePrices.reduce(
            (acc: number, next: number) => acc + next,
            0
          )

          delivery.price = total / 100
        }

        const deliveryWindow: any =
          delivery.availableDeliveryWindows?.length > 0
            ? delivery.availableDeliveryWindows[0]
            : {}

        if (
          deliveryWindow?.startDateUtc &&
          deliveryWindow?.startDateUtc !== ''
        ) {
          slaItems.forEach((item) => {
            defaultLogistics.push({
              itemIndex: item,
              selectedSla: delivery.id,
              selectedDeliveryChannel: delivery.deliveryChannel,
              deliveryWindow: {
                startDateUtc: deliveryWindow.startDateUtc,
                endDateUtc: deliveryWindow.endDateUtc,
              },
            })
          })
        } else {
          slaItems.forEach((item) => {
            defaultLogistics.push({
              itemIndex: item,
              selectedSla: delivery.id,
              selectedDeliveryChannel: delivery.deliveryChannel,
            })
          })
        }

        totalItems = totalItems.filter((el) => !slaItems.includes(el))
      } else if (pickupSlas.length > 0) {
        const [pickup] = pickupSlas
        let slaItems = pickup.itemIndex

        slaItems = slaItems.filter((item: number) => !itemsUsed.includes(item))
        slaItems.forEach((item) => itemsUsed.push(item))
        if (slaItems.length !== pickup.itemIndex.length) {
          const newPriceByItem = pickup.prices.filter((itemIndex) => {
            const item = parseInt(Object.keys(itemIndex)[0], 10)

            return slaItems.includes(item)
          })

          const usedPrices = newPriceByItem.map((price) => Object.values(price))
          const mergePrices = [].concat([], ...usedPrices)
          const total = mergePrices.reduce(
            (acc: number, next: number) => acc + next,
            0
          )

          pickup.price = total / 100
        }

        const deliveryWindow: any =
          pickup.availableDeliveryWindows?.length > 0
            ? pickup.availableDeliveryWindows[0]
            : {}

        if (
          deliveryWindow?.startDateUtc &&
          deliveryWindow?.startDateUtc !== ''
        ) {
          slaItems.forEach((item) => {
            defaultLogistics.push({
              itemIndex: item,
              selectedSla: pickup.id,
              selectedDeliveryChannel: pickup.deliveryChannel,
              deliveryWindow: {
                startDateUtc: deliveryWindow.startDateUtc,
                endDateUtc: deliveryWindow.endDateUtc,
              },
            })
          })
        } else {
          slaItems.forEach((item) => {
            defaultLogistics.push({
              itemIndex: item,
              selectedSla: pickup.id,
              selectedDeliveryChannel: pickup.deliveryChannel,
            })
          })
        }

        totalItems = totalItems.filter((el) => !slaItems.includes(el))
      } else {
        totalItems = []
      }

      // eslint-disable-next-line no-loop-func
      deliverySlas = deliverySlas.filter((delivery) => {
        const availableItems = delivery.itemIndex.filter((index) =>
          totalItems.includes(index)
        )

        return availableItems.length > 0
      })
      // eslint-disable-next-line no-loop-func
      pickupSlas = pickupSlas.filter((pickup) => {
        const availableItems = pickup.itemIndex.filter((index) =>
          totalItems.includes(index)
        )

        return availableItems.length > 0
      })
    } while (totalItems.length > 0)
  }

  return defaultLogistics
}

const getTotalById = (id: TotalizerId, totalizers: Totalizer[]) =>
  totalizers?.find((totalizer) => totalizer.id === id) || {
    value: 0,
  }

export const totalShipping = (totalizers: Totalizer[]) => {
  const items = getTotalById('Items', totalizers)
  const shipping = getTotalById('Shipping', totalizers)
  const tax = getTotalById('Tax', totalizers)
  const discounts = getTotalById('Discounts', totalizers)

  return items.value + shipping.value + tax.value + discounts.value
}

export const existUnavailableProducts = (items: ItemSimulation[]) =>
  items?.filter(
    (item) =>
      item?.availability !== 'available' &&
      item?.availability !== 'cannotBeDelivered'
  ).length > 0

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useUpdateSelectedAddress.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMutation } from '@apollo/client'
import { useDispatch, useSelector } from 'react-redux'

import { UPDATE_SELECTED_ADDRESS } from '../graphql/mutations'
import {
  selectShipping,
  setUpdateAddresses,
} from '../contexts/global-context/reducers/orderFormDataSlice'

export const useUpdateSelectedAddress = (selectedAddress: string) => {
  const { availableAddresses } = useSelector(selectShipping)
  const dispatch = useDispatch()

  const [updateSelectedAddress] = useMutation(UPDATE_SELECTED_ADDRESS, {
    onCompleted: () => {
      dispatch(
        setUpdateAddresses({
          selectedAddress: availableAddresses?.find(
            (address) => address.id === selectedAddress
          ),
        })
      )
    },
    onError: (e) => {
      console.error('error: ', e)
    },
  })

  return {
    updateSelectedAddress,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useCustomCss.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useEffect, useState } from 'react'

const useCustomCss = (account: string, sandbox: boolean) => {
  const _CSSProp = `https://d3pdfqr5jxqzs1.cloudfront.net/${account}-vtex-mc.css`
  const _CSSDev = `https://mycheckout-custom-css-qa.s3.amazonaws.com/${account}-vtex-mc.css`
  const [customCss, setCustomCss] = useState(false)

  useEffect(() => {
    if (!customCss) {
      const css = document.createElement('link')

      css.rel = 'stylesheet'
      css.type = 'text/css'
      css.href = sandbox ? _CSSDev : _CSSProp
      css.id = 'custom-css-mc'

      document.head.appendChild(css)

      if (document.getElementById('custom-css-mc')) setCustomCss(true)
    }
  }, [])
}

export default useCustomCss

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useFetchIpAddress.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useEffect, useState } from 'react'

import { getIpAddress } from '../services/getIpAdrress'

export const useFetchIpAddress = () => {
  const [ipAddress, setIpAddress] = useState<string>(null)

  useEffect(() => {
    getIpAddress().then((ip) => {
      setIpAddress(ip)
    })
  }, [])

  return { ipAddress }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useGeoLocation.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useState, useEffect } from 'react'

interface Error {
  code: number
  message: string
}

const useGeolocation = () => {
  const [location, setLocation] = useState({
    loaded: false,
    coordinates: { lat: '', lng: '' },
    error: 0,
  })

  const onSuccess = (location1: any) => {
    setLocation({
      loaded: true,
      coordinates: {
        lat: location1.coords.latitude,
        lng: location1.coords.longitude,
      },
      error: 200,
    })
  }

  const onError = (error: Error) => {
    setLocation({
      loaded: true,
      coordinates: { lat: '', lng: '' },
      error: error.code,
    })
  }

  useEffect(() => {
    if (!('geolocation' in navigator)) {
      onError({
        code: 0,
        message: 'Geolocation not supported',
      })
    }

    navigator.geolocation.getCurrentPosition(onSuccess, onError)
  }, [])

  return location
}

export default useGeolocation

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useInitializeAll.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useEffect } from 'react'
import { pathOr } from 'ramda'
import { useDispatch, useSelector } from 'react-redux'

import { useActionsDispatch } from '../contexts/ActionsProviderV2'
import { useUserData, useUserDataDispatch } from '../contexts/UserDataProvider'
import {
  selectLoadingAction,
  selectStep,
  setLoadingAction,
} from '../contexts/global-context/reducers/checkoutFormSlice'
import type {
  ClientProfileData,
  Config,
  ItemToAdd,
  ItemToRemove,
  OfferingInput,
  OrderForm,
  Product,
  ProductItem,
  ResponseValidateItem,
  ShowPaymentMethod,
  StoreTermsAndConditionsContent,
} from '../interfaces'
import {
  selectOrderForm,
  setAddressStore,
  setEmail,
  setItems,
  setPaymentsOrderForm,
} from '../contexts/global-context/reducers/orderFormDataSlice'
import type { Card, Payment } from '../interfaces/orderForm'

interface Props {
  config?: Partial<Config>
  customData?: any
  hideDiscount: boolean
  itemToAdd?: ItemToAdd
  orderForm: OrderForm
  product?: Product
  selectedItem?: ProductItem
  showPaymentMethods?: ShowPaymentMethod[]
  skuSelectorProps?: {
    visibleVariations?: string[]
    useImageInColor?: boolean
  }
  storeTermsAndConditionsContent?: StoreTermsAndConditionsContent[]
  addItemOffering?: (offeringInput: OfferingInput) => void
  addToCart: (item: ItemToAdd) => void
  clearData: (items: ItemToRemove[]) => void
  handleGetDocumentsClient?: (email: string) => void
  handleSelectedItem?: (item: ProductItem) => void
  insertCoupon?: (text: string) => void
  removeItemOffering?: (offeringInput: OfferingInput) => void
  updateItems: (items: ItemToRemove[]) => void
  updateOrderFormProfile: (profile: ClientProfileData) => void
  validateItems?: () => ResponseValidateItem[] | []
}

export const useInitializeAll = ({
  config,
  customData,
  hideDiscount,
  orderForm,
  showPaymentMethods,
  skuSelectorProps,
  storeTermsAndConditionsContent,
  addItemOffering,
  addToCart,
  clearData,
  handleGetDocumentsClient,
  handleSelectedItem,
  insertCoupon,
  removeItemOffering,
  updateItems,
  updateOrderFormProfile,
  validateItems,
}: Props) => {
  const dispatchUserData = useUserDataDispatch()
  const dispatchActions = useActionsDispatch()
  const dispatchGlobal = useDispatch()
  const userData = useUserData()
  const step = useSelector(selectStep)
  const loadingAction = useSelector(selectLoadingAction)
  const { items } = useSelector(selectOrderForm)

  useEffect(() => {
    dispatchActions({
      type: 'SET_INITIAL_CONFIG',
      args: {
        config,
        hideDiscount,
        showPaymentMethods,
        skuSelectorProps,
        storeTermsAndConditionsContent,
        addItemOffering,
        addToCart,
        clearData,
        handleGetDocumentsClient,
        handleSelectedItem,
        insertCoupon,
        removeItemOffering,
        updateItems,
        updateOrderFormProfile,
        validateItems,
      },
    })
  }, [])

  useEffect(() => {
    if (config) {
      dispatchActions({
        type: 'SET_STORE_CONFIG',
        args: config,
      })
    }
  }, [config])

  useEffect(() => {
    const itemsUserData = pathOr([], ['items'], orderForm)

    if (loadingAction && itemsUserData?.length > 0) {
      dispatchGlobal(setLoadingAction(false))
    }

    dispatchUserData({
      type: 'SET_ITEMS',
      args: itemsUserData,
    })
  }, [orderForm])

  useEffect(() => {
    if (step === 3) {
      dispatchActions({
        type: 'SET_IS_LOADING_CVV_FIELD',
        args: false,
      })
    }
  }, [step])

  useEffect(() => {
    if (showPaymentMethods?.length) {
      dispatchActions({
        type: 'SET_SHOW_PAYMENT_METHODS',
        args: showPaymentMethods,
      })
    }
  }, [showPaymentMethods])

  useEffect(() => {
    if (!orderForm) return

    const clientProfileData: { email?: string; loadData: boolean } = {
      loadData: userData.clientProfileData.loadData || false,
    }

    // TODO: If we take the information from the cart simulation, we don't need take information from the vtex orderForm
    dispatchUserData({
      type: 'SET_ORDER_FORM',
      args: {
        clientProfileData,
        items: orderForm.items,
        totalizers: orderForm.totalizers,
        value: orderForm.value,
        messages: orderForm.messages,
        marketingData: orderForm.marketingData, // Keep
        paymentData: orderForm.paymentData,
        ratesAndBenefitsData: orderForm.ratesAndBenefitsData,
        // shippingData: orderForm.shippingData,
        // logisticsInfo: orderForm.logisticsInfo,
      },
    })

    dispatchUserData({
      type: 'SET_CUSTOM_DATA',
      args: customData || null, // Keep
    })
  }, [orderForm])

  // Start new context initialization
  useEffect(() => {
    if (JSON.stringify(items) === JSON.stringify(orderForm?.items)) return
    dispatchGlobal(setItems(orderForm?.items || []))
  }, [orderForm?.items])

  useEffect(() => {
    if (!orderForm?.shippingData?.addressAlternative) return

    const { addressAlternative } = orderForm?.shippingData

    const addressInfo = {
      id: addressAlternative?.addressId,
      city: addressAlternative?.city,
      complement: addressAlternative?.reference,
      country: addressAlternative?.country,
      geoCoordinates: {
        latitude: addressAlternative?.geoCoordinates?.latitude,
        longitude: addressAlternative?.geoCoordinates?.longitude,
      },
      neighborhood: addressAlternative?.neighborhood,
      postalCode: addressAlternative?.postalCode,
      receiverName: addressAlternative?.receiverName,
      reference: addressAlternative?.reference,
      state: addressAlternative?.state,
      street: addressAlternative?.street,
      number: addressAlternative?.number,
      selectedSlaId: addressAlternative?.selectedSlaId,
    }

    // TODO: Reducir condicional
    if (addressAlternative?.addressType === 'residential') {
      dispatchGlobal(
        setAddressStore({
          ...addressInfo,
          addressDeliveryType: 'delivery',
        })
      )
    } else if (addressAlternative?.addressType === 'search') {
      dispatchGlobal(
        setAddressStore({
          ...addressInfo,
          addressDeliveryType: 'pickup',
        })
      )
    }
  }, [orderForm?.shippingData?.addressAlternative])

  useEffect(() => {
    const persistedData = localStorage.getItem('checkoutless_data')
    const localEmail = persistedData && JSON.parse(persistedData)

    dispatchGlobal(
      setEmail(
        orderForm?.clientProfileData?.email ||
          (localEmail && localEmail.email) ||
          null
      )
    )
  }, [orderForm?.clientProfileData?.email])

  useEffect(() => {
    const availableCards: Card[] =
      orderForm?.paymentData?.availablePaymentMethods.map((payment) => ({
        bin: payment.bin,
        cardId: payment.id,
        franchise: payment.franchise,
        number: payment.number,
        gateway: payment.gateway,
      }))

    const payments: Payment[] =
      orderForm?.paymentData?.availablePaymentMethods.map((payment) => ({
        bin: payment.bin,
        cardId: payment.id,
        franchise: payment.franchise,
        number: payment.number,
        paymentId: payment.paymentId,
        paymentMethod: payment.paymentMethod,
        origin: payment.origin,
      }))

    const firstItemCard = orderForm?.paymentData?.availablePaymentMethods[0]
    const selectedCard: Card = firstItemCard && {
      cardId: firstItemCard?.id,
      bin: firstItemCard?.bin,
      franchise: firstItemCard?.franchise,
      number: firstItemCard?.number,
      gateway: firstItemCard?.gateway,
    }

    if (selectedCard) {
      dispatchGlobal(
        setPaymentsOrderForm({
          availableCards,
          payment: payments,
          selectedCard,
        })
      )
    }
  }, [orderForm?.paymentData?.availablePaymentMethods])
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useCustomerCredit.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useCallback, useEffect, useMemo, useState } from 'react'
import { useLazyQuery } from '@apollo/client'
import { useSelector } from 'react-redux'

import { useUserData } from '../contexts/UserDataProvider'
import { VALIDATE_CREDIT } from '../graphql/queries'
import type { ICredit, ISimulationCredit } from '../interfaces'
import { selectProfile } from '../contexts/global-context/reducers/orderFormDataSlice'

export interface ISimulationCreditResponse {
  validateCredit?: {
    approvedCredit?: number
    maxInstallments?: number
  }
}

export const useCustomerCredit = () => {
  const { value } = useUserData()
  const { email } = useSelector(selectProfile)
  const [credit, setCredit] = useState<ICredit | null>(null)
  const [validateCredit, setValidate] = useState<boolean>(true)
  const [isCalled, setIsCalled] = useState<boolean>(false)
  const [canPayWithCredit, setCanPayWithCredit] = useState<boolean>(false)
  const [showMinMessage, setShowMinMessage] = useState<boolean>(false)
  const [simulationCredit, setSimulationCredit] =
    useState<ISimulationCredit | null>(null)

  const [validate] = useLazyQuery(VALIDATE_CREDIT, {
    fetchPolicy: 'network-only',
    onCompleted: (response: ISimulationCreditResponse) => {
      setCredit({
        credit: !!response?.validateCredit?.approvedCredit,
        approved: response?.validateCredit?.approvedCredit,
        installments: response?.validateCredit?.maxInstallments,
      })
      setValidate(false)
      setIsCalled(true)
    },
    onError: () => {},
  })

  useEffect(() => {
    if (credit) {
      setCanPayWithCredit(credit?.credit)
    }

    return () => {
      setCanPayWithCredit(null)
    }
  }, [credit])

  useEffect(() => {
    if (value < 100000) {
      return setSimulationCredit({
        quotaQuantity: 3,
        quotaValue: value / 3,
      })
    }

    if (value > 100000 && value < 1000000) {
      return setSimulationCredit({
        quotaQuantity: 12,
        quotaValue: value / 12,
      })
    }

    if (value > 1000001) {
      return setSimulationCredit({
        quotaQuantity: 24,
        quotaValue: value / 24,
      })
    }

    return () => {
      setSimulationCredit(null)
    }
  }, [value])

  const onSimulationCredit = useCallback(() => {
    email &&
      value &&
      validate({
        variables: {
          email,
          totals: value,
        },
      })
  }, [email, credit, value])

  const onChangePaymet = useCallback(() => {
    if (credit?.credit) return setShowMinMessage(true)
  }, [email, credit])

  return useMemo(
    () => ({
      credit,
      simulationCredit,
      validateCredit,
      canPayWithCredit,
      onSimulationCredit,
      isCalled,
      showMinMessage,
      onChangePaymet,
    }),
    [
      credit,
      simulationCredit,
      validateCredit,
      canPayWithCredit,
      onSimulationCredit,
      isCalled,
      showMinMessage,
      onChangePaymet,
    ]
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useDebounceInput.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useEffect, useState } from 'react'

export function useSearchDebounce(delay = 1000) {
  const [search, setSearch] = useState(null)
  const [searchQuery, setSearchQuery] = useState(null)

  useEffect(() => {
    const delayFn = setTimeout(() => setSearch(searchQuery), delay)

    return () => clearTimeout(delayFn)
  }, [searchQuery, delay])

  return [search, setSearchQuery]
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useUnits.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMemo } from 'react'

import type { Item } from '../interfaces'

export const useUnits = (items: Item[]) => {
  const units = useMemo(
    () =>
      items.reduce((acc, el) => {
        return acc + (el?.quantity || 0)
      }, 0),
    [items]
  )

  return units
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useLogisticBlock.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useEffect, useState } from 'react'
import { useSelector } from 'react-redux'

import { selectBlockedShipping } from '../contexts/global-context/reducers/checkoutFormSlice'
import { selectItems } from '../contexts/global-context/reducers/orderFormDataSlice'

const useLogisticBlock = () => {
  const items = useSelector(selectItems)

  const [logisticsBlocked, setLogisticsBlocked] = useState(false)

  const blockedShipping = useSelector(selectBlockedShipping)

  useEffect(() => {
    blockedShipping.categories.forEach((category) => {
      items.forEach((item) => {
        if (item?.productCategoryIds?.search(category.id) !== -1) {
          setLogisticsBlocked(true)

          return null
        }
      })
    })
  }, [blockedShipping, items])

  return {
    logisticsBlocked,
  }
}

export default useLogisticBlock

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useInitSecureFields.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useState, useEffect } from 'react'

import { useScript } from './useScript'
import { usePCIScript } from './usePCIScript'

export const useInitSecureFields = (
  _: string,
  paymentMethod?: string,
  cvcRequired?: boolean
) => {
  const [loadPaymentForm, setLoadPaymentForm] = useState(false)
  const { PCI_PROXY_SCRIPT } = usePCIScript()

  useEffect(() => {
    if (paymentMethod === 'tc' && cvcRequired) {
      if (!(window as any).SecureFieldsCVCLoad) {
        useScript(PCI_PROXY_SCRIPT[0], PCI_PROXY_SCRIPT[1]).then(() => {
          // eslint-disable-next-line prettier/prettier
          ;(window as any).SecureFieldsCVCLoad = true
          setLoadPaymentForm(true)
        })
      }

      if ((window as any).SecureFieldsCVCLoad && !loadPaymentForm) {
        setLoadPaymentForm(true)
      }
    }
  }, [])

  return { loadPaymentForm }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useValidateStyles.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useSelector } from 'react-redux'

import vtexTheme from '../vtex-styles.module.css'
import kuikpayTheme from '../kuikpay-styles.module.css'
import genericTheme from '../generic-styles.module.css'
import global from '../myCheckout-styles.module.css'
import { selectTheme } from '../contexts/global-context/reducers/uiSettingsSlice'

// Solo aplica esta validación para estilos globales
export const useValidateStyles = (globalStyle = false) => {
  const theme = useSelector(selectTheme)

  if (globalStyle) {
    return global
  }

  switch (theme) {
    case 'generic':
      return genericTheme

    case 'vtex':
      return vtexTheme

    case 'kuikpay':
      return kuikpayTheme

    default:
      return global
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useCreateAddressExternal.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useState } from 'react'
import { useMutation } from '@apollo/client'
import { useDispatch, useSelector } from 'react-redux'

import { useCreateShipping } from '../components/RegisterForm/Shipping/useCreateShipping'
import type { Address } from '../interfaces'
import { CREATE_ADDRESS_EXTERNAL } from '../graphql/mutations'
import { setUserRegistrationSections } from '../contexts/global-context/reducers/checkoutFormSlice'
import type { AddressMC } from '../interfaces/orderForm'
import { selectIsNew } from '../contexts/global-context/reducers/orderFormDataSlice'

export const useCreateAddressExternal = () => {
  const [successAddressAlter, setSuccessAddressAlter] = useState(false)
  const dispatchGlobal = useDispatch()
  const { processCompletedAddress } = useCreateShipping()
  const isNew = useSelector(selectIsNew)

  const [createAddressExternal, { loading }] = useMutation(
    CREATE_ADDRESS_EXTERNAL,
    {
      onCompleted: (data) => {
        const { externalAddress } = data

        if (!isNew) return

        const addressData: Address = {
          addressId: externalAddress.id,
          addressType: 'residential',
          city: externalAddress.city,
          complement: externalAddress.reference,
          country: externalAddress.country,
          geoCoordinates: {
            latitude: externalAddress.geoCoordinates.latitude,
            longitude: externalAddress.geoCoordinates.longitude,
          },
          neighborhood: externalAddress.neighborhood,
          postalCode: externalAddress.postalCode,
          receiverName: externalAddress.receiverName,
          reference: externalAddress.reference,
          state: externalAddress.state,
          street: externalAddress.street,
        }

        if (externalAddress?.isEqual && externalAddress?.isEqual === 'false') {
          setSuccessAddressAlter(true)
          setTimeout(() => {
            setSuccessAddressAlter(false)
          }, 3000)
        }

        dispatchGlobal(setUserRegistrationSections(3))
        processCompletedAddress(addressData, true)
      },
      onError: (error) => {
        console.error('ERROR CREATE ADDRESS EXTERNAL', error)
        setSuccessAddressAlter(false)
      },
    }
  )

  const verifyAndCreateAlternativeAddress = async (
    userData: any,
    addressAlternative: AddressMC
  ) => {
    let addressAlternativeWhitPostalCode = userData.addresses?.find(
      (address: any) => address?.id === addressAlternative?.id
    )

    if (
      addressAlternative &&
      (addressAlternative?.postalCode?.includes('*') ||
        !addressAlternativeWhitPostalCode)
    ) {
      const dataForCreate = {
        addressId: addressAlternative?.id,
        profileId: userData?.id,
        country: addressAlternative?.country,
        state: addressAlternative?.state,
        city: addressAlternative?.city,
        street: addressAlternative?.street,
        number: addressAlternative?.number,
        postalCode: addressAlternative?.postalCode,
        receiverName: addressAlternative?.receiverName || '',
        geoCoordinates: addressAlternative?.geoCoordinates,
        neighborhood: addressAlternative?.neighborhood || '',
        reference: addressAlternative?.reference,
      }

      addressAlternativeWhitPostalCode = await createAddressExternal({
        variables: { args: dataForCreate },
      })
    }

    return addressAlternativeWhitPostalCode?.data?.externalAddress
      ? {
          ...addressAlternativeWhitPostalCode?.data?.externalAddress,
          addressDeliveryType: addressAlternative?.addressDeliveryType,
        }
      : addressAlternative
  }

  return {
    loading,
    successAddressAlter,
    createAddressExternal,
    setSuccessAddressAlter,
    verifyAndCreateAlternativeAddress,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useFonts.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { pathOr } from 'ramda'
import { useSelector } from 'react-redux'

import { selectSettings } from '../contexts/global-context/reducers/uiSettingsSlice'

export const useFonts = () => {
  const { styles: stylesContext } = useSelector(selectSettings)

  const fonts = pathOr(
    "'Calibri', sans-serif;",
    ['modal', 'font'],
    JSON.parse(stylesContext || '{}')
  )

  return {
    fonts,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useSelectValue.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useState } from 'react'

interface Option {
  label: string
  value: string
}

export const useSelectValue = (initialValue: Option) => {
  const [value, setValue] = useState(initialValue)
  const [isValid, setIsValid] = useState(null)
  const onChange = (option: Option) => {
    setValue(option)
  }

  const reset = () => {
    setValue(null)
    setIsValid(null)
  }

  return { value, onChange, isValid, setIsValid, reset, setValue }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useAvailablePaymentMethods.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMemo } from 'react'
import { useSelector } from 'react-redux'

import { selectOrderForm } from '../contexts/global-context/reducers/orderFormDataSlice'
import type { Card } from '../interfaces/orderForm'

const useAvailablePaymentMethods = () => {
  const {
    payments: { availableCards },
  } = useSelector(selectOrderForm)

  const availablePaymentMethods = useMemo(() => {
    const payments = availableCards
    const newPayments: Card[] = []
    let indexJ = 0

    for (let i = 0; i < payments.length; i++) {
      indexJ = i
      for (indexJ; indexJ < payments.length; indexJ++) {
        const primaryPos = payments[i]
        const secondaryPos = payments[indexJ]

        const cardPrimaryPos =
          primaryPos?.bin?.concat(primaryPos?.number) || null

        const cardSecondaryPos =
          secondaryPos?.bin?.concat(secondaryPos?.number) || null

        const isSecondaryOrigin =
          primaryPos?.origin &&
          primaryPos?.origin === 'store' &&
          !secondaryPos?.origin

        if (
          cardPrimaryPos &&
          cardSecondaryPos &&
          cardPrimaryPos === cardSecondaryPos &&
          isSecondaryOrigin
        ) {
          break
        }

        if (
          indexJ === payments.length - 1 &&
          (!primaryPos?.origin ||
            (primaryPos?.origin &&
              !newPayments.find(
                (item) => item?.bin?.concat(item.number) === cardPrimaryPos
              )))
        ) {
          newPayments.push(primaryPos)
        }
      }
    }

    return newPayments
  }, [availableCards])

  return { availablePaymentMethods }
}

export default useAvailablePaymentMethods

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useScript.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
export const useScript = async (url: string, type: string) =>
  new Promise((resolve, reject) => {
    let ready = false

    if (!document) {
      reject(new Error('Document is not defined'))
    }

    if (type === 'script') {
      const script = document.createElement('script')

      script.src = url
      script.async = true
      script.charset = 'UTF-8'

      script.onload = function () {
        if (
          !ready &&
          (!(this as any).readyState || (this as any).readyState === 'complete')
        ) {
          ready = true
          resolve(script)
        }
      }

      script.onerror = (msg) => {
        console.error(msg)
        reject(new Error('Error loading script.'))
      }

      script.onabort = (msg) => {
        console.error(msg)
        reject(new Error('Script loading aboirted.'))
      }

      document.head.appendChild(script)
    } else {
      const link = document.createElement('link')

      link.href = url
      link.rel = 'stylesheet'
      link.type = 'text/css'

      document.head.appendChild(link)
    }
  })

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useSimulation.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
/* eslint-disable vtex/prefer-early-return */
import { useEffect, useState } from 'react'
import _ from 'lodash'

import { useUserData, useUserDataDispatch } from '../contexts/UserDataProvider'
import { useActions } from '../contexts/ActionsProviderV2'
import type { LogisticsInfo, CartSimulation, Item } from '../interfaces'
import constants from '../utils/constants'
import {
  defaultPackages,
  slasSummary,
  totalShipping,
} from '../utils/simulation'

export const useSimulation = () => {
  const {
    items,
    shippingData,
    logisticsInfo,
    totalizers,
    changeLogistics,
    slas,
    marketingData,
    paymentData,
    clientProfileData,
    ratesAndBenefitsData,
  } = useUserData()

  const [oldDataCartSimulation, setOldDataCartSimulation] = useState<any>({})
  const [payment, setPayment] = useState({})

  const { cartSimulation } = useActions()
  const dispatchUserData = useUserDataDispatch()

  const simulationItems = (newItems: Item[], resultItems: any[]): any[] => {
    return newItems.map((item: Item, index: number) => {
      if (!resultItems?.[index]) return item
      const { availability, price, sellingPrice, priceTags }: any = resultItems
        ? resultItems?.[index]
        : false

      const newPriceTags = priceTags?.map((priceTag: any) => {
        const lastPriceTag = item.priceTags?.find(
          (lastTag: any) =>
            priceTag?.name?.includes(lastTag?.identifier) ||
            lastTag?.name === priceTag?.name
        )

        return {
          ...priceTag,
          identifier: lastPriceTag?.identifier || priceTag?.identifier,
        }
      })

      return {
        ...item,
        availability,
        price: price / 100,
        sellingPrice: sellingPrice / 100,
        priceTags: newPriceTags,
      }
    })
  }

  // Valida segundo metodo de entrega
  const validateSecondMethod = (data: any) => {
    cartSimulation(data)
      .then((response: any) => response?.json())
      .then((result: CartSimulation) => {
        const resultItems = simulationItems(data?.items, result?.items)
        const newItems = items.map((item: Item) => {
          const dataFind = resultItems.find((simItem) => simItem.id === item.id)

          return dataFind || item
        })

        dispatchUserData({
          type: 'SET_BENEFITS',
          args: {
            items: newItems,
            ratesAndBenefitsData,
          },
        })
      })
  }

  useEffect(() => {
    let updateWhenChangeItems = false
    let simulationLogistics: LogisticsInfo[] = []

    if (
      (shippingData.selectedAddress &&
        Object.prototype.hasOwnProperty.call(
          shippingData.selectedAddress,
          'street'
        )) ||
      (shippingData?.addressAlternative &&
        shippingData?.addressAlternative?.addressType !== 'residential') ||
      clientProfileData?.completed
    ) {
      const orderItems = items
        ?.map((item: Item) => {
          return {
            id: item.id,
            seller: item.seller,
            quantity: item.quantity,
          }
        })
        .filter(
          (item, i) =>
            items.findIndex((searchItem) => searchItem.id === item.id) === i
        )

      if (items.length <= logisticsInfo?.length) {
        simulationLogistics = logisticsInfo?.map((item: LogisticsInfo) => {
          return {
            ...item,
            selectedSlaId: item.selectedSla,
            selectedDeliveryWindow: item.deliveryWindow,
          }
        })
      } else {
        updateWhenChangeItems = true
      }

      const { selectedAddress } = shippingData
      let newGeoCoordinates: string[] = []

      if (selectedAddress?.geoCoordinates) {
        const {
          geoCoordinates: { longitude, latitude },
        } = selectedAddress

        if (longitude !== '' && latitude !== '') {
          newGeoCoordinates = [longitude, latitude]
        } else if (
          shippingData?.addressAlternative &&
          shippingData?.addressAlternative?.addressType === 'residential'
        ) {
          const { geoCoordinates } = shippingData?.addressAlternative

          if (
            geoCoordinates?.longitude !== '' &&
            geoCoordinates?.latitude !== ''
          ) {
            newGeoCoordinates = [
              geoCoordinates?.longitude,
              geoCoordinates?.latitude,
            ]
          }
        }
      }

      const dataCartSimulation: any = {
        items: orderItems,
        postalCode: shippingData.selectedAddress?.postalCode,
        country: constants.countryCode,
        geoCoordinates: newGeoCoordinates,
        clientProfileData: {
          email: clientProfileData?.email,
        },
        shippingData: {
          logisticsInfo: simulationLogistics,
        },
        marketingData: marketingData?.coupon ? marketingData : null,
      }

      if (
        shippingData?.addressAlternative &&
        shippingData?.addressAlternative?.addressType !== 'residential'
      ) {
        const { addressAlternative } = shippingData

        dataCartSimulation.postalCode = addressAlternative?.postalCode
        if (Object.keys(addressAlternative?.geoCoordinates).length !== 0) {
          const {
            geoCoordinates: { longitude, latitude },
          } = addressAlternative

          if (longitude !== '' && latitude !== '') {
            dataCartSimulation.geoCoordinates = [longitude, latitude]
          }
        }
      }

      if (
        paymentData?.selectedPaymentMethod?.paymentSystem ||
        paymentData?.selectedPaymentMethod?.paymentMethod ||
        paymentData?.temporalPaymentSystem
      ) {
        dataCartSimulation.paymentData = {
          payments: [
            {
              bin: paymentData.bin
                ? paymentData.bin
                : paymentData?.selectedPaymentMethod?.bin,
              paymentSystem: paymentData?.temporalPaymentSystem
                ? paymentData?.temporalPaymentSystem
                : paymentData?.selectedPaymentMethod?.paymentSystem
                ? paymentData?.selectedPaymentMethod?.paymentSystem
                : paymentData?.selectedPaymentMethod?.paymentMethod,
            },
          ],
        }
      }

      const simulationObjectIsEqual = _.isEqual(
        dataCartSimulation,
        oldDataCartSimulation
      )

      if (!simulationObjectIsEqual) {
        setOldDataCartSimulation(dataCartSimulation)
        cartSimulation(dataCartSimulation)
          // eslint-disable-next-line @typescript-eslint/no-explicit-any
          .then((response: any) => response?.json())
          .then((result: CartSimulation) => {
            const slaSummary = slasSummary(result?.logisticsInfo)

            let logistictsInfo
            const resultItems = simulationItems(items, result?.items)

            dispatchUserData({
              type: 'SET_ITEMS',
              args: resultItems,
            })

            setPayment(result?.paymentData)

            dispatchUserData({
              type: 'SET_BENEFITS',
              args: {
                items: resultItems,
                ratesAndBenefitsData: result.ratesAndBenefitsData,
              },
            })

            if (slas.dontUpdateLogistics) {
              logistictsInfo = logisticsInfo
            } else {
              logistictsInfo = defaultPackages(
                slaSummary,
                resultItems,
                shippingData?.addressAlternative
              )
            }

            const totalizersArgs =
              result?.totals?.length > 0 ? result?.totals : totalizers

            const total = totalShipping(totalizersArgs)

            dispatchUserData({
              type: 'SET_VALUE',
              args: total / 100,
            })
            dispatchUserData({
              type: 'SET_TOTALIZERS',
              args: totalizersArgs,
            })
            dispatchUserData({
              type: 'SET_SLAS',
              args: {
                ...slaSummary,
                packages: slas.packages,
                dontUpdateLogistics: false,
                updateWhenChangeItems,
              },
            })
            dispatchUserData({
              type: 'SET_LOGISTICS_INFO',
              args: logistictsInfo,
            })
            dispatchUserData({
              type: 'SET_INSTALLMENTS',
              args: result?.paymentData?.installmentOptions || [],
            })

            if (shippingData?.addressAlternative) {
              if (
                shippingData?.addressAlternative?.addressType === 'search' &&
                logistictsInfo.some(
                  (x) => x.selectedDeliveryChannel === 'delivery'
                ) &&
                shippingData?.selectedAddress &&
                Object.keys(shippingData?.selectedAddress).length !== 0
              ) {
                const logisticsDelivery = logistictsInfo.filter(
                  (x) => x.selectedDeliveryChannel === 'delivery'
                )

                const productsDelivery: any[] = []

                logisticsDelivery.forEach((logistic: any) => {
                  if (resultItems?.[logistic?.itemIndex]) {
                    productsDelivery.push(resultItems?.[logistic?.itemIndex])
                  }
                })

                const dataToSimulate = {
                  items: productsDelivery,
                  postalCode: shippingData.selectedAddress?.postalCode,
                  country: constants.countryCode,
                  geoCoordinates: newGeoCoordinates,
                  clientProfileData: {
                    email: clientProfileData?.email,
                  },
                  shippingData: {
                    logisticsInfo: logisticsDelivery,
                  },
                  marketingData: marketingData?.coupon ? marketingData : null,
                }

                validateSecondMethod(dataToSimulate)
              }
            }
          })
      }
    }
  }, [
    shippingData,
    changeLogistics,
    paymentData?.selectedPaymentMethod?.bin,
    paymentData?.bin,
    paymentData?.temporalPaymentSystem,
    clientProfileData?.completed,
  ])

  const paymentInfo = {
    paymentData: payment || paymentData.selectedPaymentMethod,
    paymentDataSimulation: payment,
  }

  return { logisticsInfo, paymentInfo }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useDeliveryPromise.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useIntl } from 'react-intl'

export const useDeliveryPromise = (shippingEstimate: string) => {
  const intl = useIntl()
  let time = ''
  let textTime

  if (shippingEstimate === '0bd') {
    time = shippingEstimate.substring(0, shippingEstimate.length - 2)
    textTime = intl.formatMessage({
      id: 'store/checkoutless.logistics.sameDay',
    })
  } else if (shippingEstimate.includes('bd')) {
    time = shippingEstimate.substring(0, shippingEstimate.length - 2)
    textTime = intl.formatMessage({
      id: 'store/checkoutless.logistics.businessDays',
    })
  } else if (shippingEstimate.includes('d')) {
    time = shippingEstimate.substring(0, shippingEstimate.length - 1)
    textTime = intl.formatMessage({
      id: 'store/checkoutless.logistics.days',
    })
  } else if (shippingEstimate.includes('m')) {
    time = shippingEstimate.substring(0, shippingEstimate.length - 1)
    textTime = intl.formatMessage({
      id: 'store/checkoutless.logistics.minutes',
    })
  }

  return {
    time,
    textTime,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useInputValue.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useState } from 'react'

export const useInputValue = (
  initialValue: string,
  beforeOfChange?: (value: string) => string,
  beforeOfReset?: () => void
) => {
  const [value, setValue] = useState(initialValue)
  const [isValid, setIsValid] = useState(null)
  const onChange = (
    e: React.ChangeEvent<HTMLInputElement | HTMLSelectElement>
  ) => {
    let newValue = e.target.value

    if (beforeOfChange && beforeOfChange instanceof Function) {
      newValue = beforeOfChange(newValue)
    }

    setValue(newValue)
  }

  const reset = () => {
    if (beforeOfReset && beforeOfChange instanceof Function) {
      beforeOfReset()
    }

    setValue('')
    setIsValid(null)
  }

  return { value, isValid, setIsValid, onChange, reset, setValue }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/usePaymentInfo.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useMemo } from 'react'
import { useSelector } from 'react-redux'

import { selectMainPayment } from '../contexts/global-context/reducers/orderFormDataSlice'
import { selectAvailablePaymentMethods } from '../contexts/global-context/reducers/simulationSlice'
import type { Card } from '../interfaces/orderForm'
import { selectIdImgCard } from '../utils/payments'

export const useCurrentPaymentMethod = (card?: Card) => {
  const selectedPayment = useSelector(selectMainPayment)
  const availablePaymentMethods = useSelector(selectAvailablePaymentMethods)

  const paymentInfo = useMemo(() => {
    const dataFranchise = selectIdImgCard(
      card ? card?.franchise : selectedPayment?.franchise
    )

    return availablePaymentMethods.find(
      (avPaymentMethod) =>
        avPaymentMethod.name.toLowerCase() === dataFranchise?.nameComplete
    )
  }, [availablePaymentMethods])

  return paymentInfo
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/usePCIScript.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMemo } from 'react'

import { useActions } from '../contexts/ActionsProviderV2'
import constant from '../utils/constants'

export const usePCIScript = () => {
  const { sandbox } = useActions()
  const PCI_PROXY_SCRIPT = useMemo(
    () => (sandbox ? constant.PCI_PROXY_SCRIPT_DEV : constant.PCI_PROXY_SCRIPT),
    [sandbox]
  )

  const merchantID = useMemo(
    () => (sandbox ? constant.merchantIDDev : constant.merchantID),
    [sandbox]
  )

  return { PCI_PROXY_SCRIPT, merchantID }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useEcommerce.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { useMutation } from '@apollo/client'

import { ECOMMERCE } from '../graphql/mutations'

export const useEcommerce = () => {
  const [ecommerce] = useMutation(ECOMMERCE, {
    onError: (e) => {
      console.error('error: ', e)
    },
  })

  const handleEcommerce = (
    event: string,
    data?: {
      products?: Array<{
        sku: string | number
        quantity: number
        price: number
        category: string
        subcategory: string
      }>
      onCompleted?: () => void
    }
  ) => {
    const email = JSON.parse(localStorage.getItem('checkoutless_data'))?.email

    ecommerce({
      variables: {
        args: {
          event,
          userEmail: email,
          data,
        },
      },
      onCompleted: (_) => {
        data?.onCompleted?.()
      },
    })
  }

  return {
    handleEcommerce,
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/hooks/useHandleVisualization.tsx from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```tsx
import { pathOr } from 'ramda'
import { useEffect, useMemo, useState } from 'react'
import { useSelector } from 'react-redux'

import { selectSettings } from '../contexts/global-context/reducers/uiSettingsSlice'
import type { Product, Visualization } from '../interfaces'

export const useHandleVisualization = (product: Product) => {
  const settings = useSelector(selectSettings)
  const visualization = useMemo(
    () => pathOr(null, ['visualization'], settings),
    [settings]
  )

  const categories = useMemo(
    () => pathOr([], ['categories'], product),
    [product]
  )

  const [hidde, setHidde] = useState(null)

  useEffect(() => {
    if (visualization === null) return
    if (!visualization.length) setHidde(false)
    if (categories.length && visualization.length) {
      const isValidated = categories.filter(
        (category) =>
          !!visualization.find((v: Visualization) => v?.key === category)
      )

      setHidde(!!isValidated.length)
    }
  }, [visualization, categories])

  const initialStyle = useMemo(
    () => ({
      display: hidde === null && 'none',
    }),
    [hidde]
  )

  return useMemo(() => ({ hidde, initialStyle }), [hidde, initialStyle])
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/removedFromCart.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Item } from '../interfaces'
import { SubmitItemRemovedFromCart } from '../services/GoogleTagManager'

interface Props {
  item: Item
  hasGoogleAnalytics?: boolean
}
export const RemovedFromCartEvent = ({ item, hasGoogleAnalytics }: Props) => {
  try {
    SubmitItemRemovedFromCart(item, hasGoogleAnalytics)
  } catch (e) {
    console.error('Error - Add To Cart Event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/enterCoupon.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { MeasurePurchaseProcess } from '../services/GoogleTagManager'
import { COUPON } from '../utils/constants'

interface Props {
  option: string
  hasGoogleAnalytics?: boolean
}
export const EnterCouponEvent = ({ option, hasGoogleAnalytics }: Props) => {
  try {
    MeasurePurchaseProcess({ stepName: COUPON, option, hasGoogleAnalytics })
  } catch (e) {
    console.error('Error - Enter email event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/fillShippingData.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { MeasurePurchaseProcess } from '../services/GoogleTagManager'
import { SHIPPING_DATA } from '../utils/constants'

interface Props {
  option: string
  hasGoogleAnalytics?: boolean
}
export const FillShippingDataEvent = ({
  option,
  hasGoogleAnalytics,
}: Props) => {
  try {
    MeasurePurchaseProcess({
      stepName: SHIPPING_DATA,
      option,
      hasGoogleAnalytics,
    })
  } catch (e) {
    console.error('Error - Fill personal data event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/enterEmail.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
interface Props {
  option: string
}
export const EnterEmailEvent = ({ option }: Props) => {
  try {
    option
  } catch (e) {
    console.error('Error - Enter email event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/buyCompleted.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Item, Totalizer } from '../interfaces'
import { SubmitBuy } from '../services/GoogleTagManager'
import { COOKIE_NAME_GTM } from '../utils/constants'

interface Props {
  items: Item[]
  transactionId: string
  totalizers: Totalizer[]
  value: number
  hasGoogleAnalytics?: boolean
}
export const BuyCompletedEvent = ({
  items,
  transactionId,
  totalizers,
  value,
  hasGoogleAnalytics = false,
}: Props) => {
  try {
    SubmitBuy(items, transactionId, totalizers, value, hasGoogleAnalytics)
    document.cookie = `${COOKIE_NAME_GTM}=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;`
  } catch (e) {
    console.error('Error - Add To Cart Event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/changeShipping.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { AddressMC } from '../interfaces/orderForm'
import { MeasurePurchaseProcess } from '../services/GoogleTagManager'
import { SHIPPING_DATA } from '../utils/constants'

interface Props {
  address: AddressMC
  hasGoogleAnalytics?: boolean
}
export const ChangeShippingEvent = ({ address, hasGoogleAnalytics }: Props) => {
  try {
    const option = `${address?.street} ${address?.city} - ${address?.state}`

    MeasurePurchaseProcess({
      stepName: SHIPPING_DATA,
      option,
      hasGoogleAnalytics,
    })
  } catch (e) {
    console.error('Error - Fill personal data event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/addToCart.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ItemToAdd, Product, ProductItem } from '../interfaces'
import { SubmitItemAddedToCart } from '../services/GoogleTagManager'

interface Props {
  selectedItem: ProductItem
  product: Product
  itemToAdd: ItemToAdd
  hasGoogleAnalytics?: boolean
}
export const AddToCartEvent = (props: Props) => {
  const { selectedItem, product, itemToAdd, hasGoogleAnalytics } = props

  try {
    SubmitItemAddedToCart({
      selectedItem,
      product,
      itemToAdd,
      hasGoogleAnalytics,
    })
  } catch (e) {
    console.error('Error - Add To Cart Event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/index.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
export { AddToCartEvent } from './addToCart.event'
export { RemovedFromCartEvent } from './removedFromCart.event'
export { BuyCompletedEvent } from './buyCompleted.event'
export { FillPersonalDataEvent } from './fillPersonalData.event'
export { EnterEmailEvent } from './enterEmail.event'
export { FillShippingDataEvent } from './fillShippingData.event'
export { FillShippingTypeDataEvent } from './fillShippingTypeData.event'
export { EnterCouponEvent } from './enterCoupon.event'
export { SelectedMethodPaymentEvent } from './selectedMethodPayment.event'
export { ChangeShippingEvent } from './changeShipping.event'

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/fillPersonalData.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { MeasurePurchaseProcess } from '../services/GoogleTagManager'
import { PERSONAL_DATA } from '../utils/constants'

interface Props {
  hasGoogleAnalytics?: boolean
}

export const FillPersonalDataEvent = ({
  hasGoogleAnalytics = false,
}: Props) => {
  try {
    MeasurePurchaseProcess({ stepName: PERSONAL_DATA, hasGoogleAnalytics })
  } catch (e) {
    console.error('Error - Fill personal data event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/fillShippingTypeData.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { MeasurePurchaseProcess } from '../services/GoogleTagManager'
import { SHIPPING_TYPE_DATA } from '../utils/constants'

interface Props {
  option: string
  hasGoogleAnalytics?: boolean
}
export const FillShippingTypeDataEvent = ({
  option,
  hasGoogleAnalytics,
}: Props) => {
  try {
    MeasurePurchaseProcess({
      stepName: SHIPPING_TYPE_DATA,
      option,
      hasGoogleAnalytics,
    })
  } catch (e) {
    console.error('Error - Fill personal data event: ', e)
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of mycheckout-sdk/src/events/selectedMethodPayment.event.ts from the mycheckout-sdk VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  CheckoutOption,
  MeasurePurchaseProcess,
} from '../services/GoogleTagManager'
import { PAYMENT } from '../utils/constants'

interface Props {
  change?: boolean
  option?: string
  hasGoogleAnalytics?: boolean
}
export const SelectedMethodPaymentEvent = ({
  change = false,
  option,
  hasGoogleAnalytics = false,
}: Props) => {
  try {
    if (change) {
      CheckoutOption({ stepName: PAYMENT, option, hasGoogleAnalytics })
    } else {
      MeasurePurchaseProcess({ stepName: PAYMENT, option, hasGoogleAnalytics })
    }
  } catch (e) {
    console.error('Error - Selected Method Payment Event: ', e)
  }
}

```