import type { SerializedLocator } from '@vitest/browser'
import type { Locator } from 'vitest/browser'
import type { BrowserCommand, BrowserCommandContext } from 'vitest/node'

export type UserEventCommand<T extends (...args: any) => any> = BrowserCommand<
  ConvertUserEventParameters<Parameters<T>>
>

type ConvertElementToLocator<T> = T extends Element | Locator ? SerializedLocator : T
type ConvertUserEventParameters<T extends unknown[]> = {
  [K in keyof T]: ConvertElementToLocator<T[K]>;
}

export function defineBrowserCommand<T extends unknown[]>(
  fn: BrowserCommand<T>,
): BrowserCommand<T> {
  return fn
}

// strip iframe locator part from the trace description e.g.
// - locator('[data-vitest="true"]').contentFrame().getByRole('button')
//     ⇓
// - getByRole('button')
export function getDescribedLocator(
  context: BrowserCommandContext,
  { locator, selector }: SerializedLocator,
): ReturnType<BrowserCommandContext['iframe']['locator']> {
  const iframeLocator = context.iframe.locator(selector)
  return typeof iframeLocator.describe === 'function'
    ? iframeLocator.describe(locator)
    : iframeLocator
}
