import {WorkshopPlugin} from '@sanity/ui-workshop'

/** @internal */
export declare interface PerfContextValue {
  activeTest?: string
  addRenderResult: (testName: string, result: PerfTestRenderResult) => void
  clearResults: (testName: string) => void
  registerTest: (test: PerfTest) => () => void
  results: PerfTestResult[]
  runTest: (testName: string) => void
  testDetails: PerfTestDetail[]
  tests: PerfTest[]
}

/** @internal */
export declare function perfPlugin(): WorkshopPlugin

/** @internal */
export declare interface PerfState {
  results: PerfTestResult[]
  activeTest?: string
  testDetails: PerfTestDetail[]
  tests: PerfTest[]
}

/** @internal */
export declare interface PerfTest<TargetType = unknown> {
  description?: string
  name: string
  title?: string
  ref: React.MutableRefObject<TargetType | null>
  run: PerfTestRunFn<TargetType>
}

/** @internal */
export declare interface PerfTestDetail {
  description?: string
  name: string
  title?: string
}

/** @beta */
export declare interface PerfTestHookProps<TargetType = unknown> {
  ref: React.MutableRefObject<TargetType | null>
  Wrapper: React.ElementType<{
    children?: React.ReactNode
  }>
}

/** @beta */
export declare interface PerfTestProps<TargetType = unknown> {
  description?: string
  name: string
  run: PerfTestRunFn<TargetType>
  title?: string
}

/**
 * @see React.ProfilerOnRenderCallback
 * @internal
 */
export declare interface PerfTestRenderResult {
  id: string
  phase: 'mount' | 'update' | 'nested-update'
  actualDuration: number
  baseDuration: number
  startTime: number
  commitTime: number
  /** @deprecated */
  interactions: Set<{
    __count: number
    id: number
    name: string
    timestamp: number
  }>
}

/** @internal */
export declare interface PerfTestResult {
  name: string
  renders: PerfTestRenderResult[]
  timing?: {
    avgDuration: number
    sumDuration: number
    runs: number
  }
}

/** @beta */
export declare type PerfTestRunFn<TargetType = unknown> = (context: {
  target: TargetType
}) => Promise<void> | void

/** @internal */
export declare function usePerf(): PerfContextValue

/** @beta */
export declare function usePerfTest<TargetType = unknown>(
  props: PerfTestProps<TargetType>,
): PerfTestHookProps<TargetType>

export {}
