import {ApiPackage} from '@microsoft/api-extractor-model'
import {ExtractorLogLevel} from '@microsoft/api-extractor'
import {ExtractorMessage} from '@microsoft/api-extractor'
import {PackageJSON} from '@sanity/pkg-utils'
import {PkgConfigOptions} from '@sanity/pkg-utils'

/** @public */
export declare interface APICallSignature {
  _type: 'api.callSignature'
  comment?: TSDocComment
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APIClass {
  _id?: string
  _type: 'api.class'
  comment?: TSDocComment
  export: APIExport
  isReactComponentType: boolean
  members: SanityArrayItem<APIConstructor | APIProperty | APIMethod>[]
  name: string
  package: APIPackage
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APIConstructor {
  _type: 'api.constructor'
  comment?: TSDocComment
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
}

/** @public */
export declare interface APIConstructSignature {
  _type: 'api.constructSignature'
  comment?: TSDocComment
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare type APIDocument =
  | APIMemberDocument
  | APIPackageDocument
  | APIReleaseDocument
  | APIExportDocument
  | APISymbolDocument

/** @public */
export declare interface APIEnum {
  _id?: string
  _type: 'api.enum'
  comment?: TSDocComment
  export: APIExport
  members: SanityArrayItem<APIEnumMember>[]
  name: string
  package: APIPackage
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
}

/** @public */
export declare interface APIEnumMember {
  _type: 'api.enumMember'
  name: string
  releaseTag?: APIReleaseTag
}

/** @public */
export declare interface APIExport {
  _type: 'api.export'
  members: SanityArrayItem<APIMember>[]
  name: string
  package: APIPackage
  path: string
  release: APIRelease
}

/** @public */
export declare type APIExportDocument = SanityDocumentValue<SerializedAPIExport>

/** @public */
export declare interface APIFunction {
  _id?: string
  _type: 'api.function'
  comment?: TSDocComment
  export: APIExport
  isReactComponentType: boolean
  isReactHook: boolean
  isOverloading: boolean
  name: string
  package: APIPackage
  parameters: SanityArrayItem<APIParameter>[]
  propsType?: APIInterface
  release: APIRelease
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
  slug: SanitySlugValue
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APIIndentifier {
  _type: 'api.identifier'
  comment?: TSDocComment
  name: string
  releaseTag?: APIReleaseTag
}

/** @public */
export declare interface APIIndexSignature {
  _type: 'api.indexSignature'
  comment?: TSDocComment
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
}

/** @public */
export declare interface APIInterface {
  _id?: string
  _type: 'api.interface'
  comment?: TSDocComment
  export: APIExport
  extends: {
    _type: 'api.extend'
    type: SanityArrayItem<APIToken>[]
  }[]
  members: SanityArrayItem<
    | APICallSignature
    | APIConstructSignature
    | APIMethodSignature
    | APIPropertySignature
    | APIIndexSignature
  >[]
  name: string
  package: APIPackage
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare type APIMember =
  | APIClass
  | APIEnum
  | APIFunction
  | APIInterface
  | APINamespace
  | APITypeAlias
  | APIVariable

/** @public */
export declare type APIMemberDocument = SanityDocumentValue<SerializedAPIMember>

/** @public */
export declare interface APIMethod {
  _type: 'api.method'
  comment?: TSDocComment
  isOptional: boolean
  isStatic: boolean
  name: string
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APIMethodSignature {
  _type: 'api.methodSignature'
  comment?: TSDocComment
  isOptional: boolean
  name: string
  parameters: SanityArrayItem<APIParameter>[]
  releaseTag?: APIReleaseTag
  returnType: SanityArrayItem<APIToken>[]
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APINamespace {
  _id?: string
  _type: 'api.namespace'
  comment?: TSDocComment
  export: APIExport
  members: SanityArrayItem<APIMember>[]
  name: string
  package: APIPackage
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
}

/** @public */
export declare interface APIPackage {
  _type: 'api.package'
  scope?: string
  name: string
  latestRelease: APIRelease
  releases: APIRelease[]
}

/** @public */
export declare type APIPackageDocument = SanityDocumentValue<SerializedAPIPackage>

/** @public */
export declare interface APIParameter {
  _type: 'api.parameter'
  comment?: TSDocComment
  name: string
  releaseTag?: APIReleaseTag
  type: SanityArrayItem<APIToken>[]
  isOptional: boolean
}

/** @public */
export declare interface APIProperty {
  _type: 'api.property'
  comment?: TSDocComment
  isEventProperty: boolean
  isOptional: boolean
  isStatic: boolean
  name: string
  releaseTag?: APIReleaseTag
  type: SanityArrayItem<APIToken>[]
}

/** @public */
export declare interface APIPropertySignature {
  _type: 'api.propertySignature'
  comment?: TSDocComment
  isOptional: boolean
  name: string
  releaseTag?: APIReleaseTag
  type: SanityArrayItem<APIToken>[]
}

/** @public */
export declare interface APIRelease {
  _type: 'api.release'
  exports: SanityArrayItem<APIExport>[]
  package: APIPackage
  memberNames: string[]
  version: string
}

/** @public */
export declare type APIReleaseDocument = SanityDocumentValue<SerializedAPIRelease>

/** @public */
export declare type APIReleaseTag = 'internal' | 'alpha' | 'beta' | 'public' | 'experimental'

/** @public */
export declare interface APISymbol {
  _type: 'api.symbol'
  name: string
  package: APIPackage
}

/** @public */
export declare type APISymbolDocument = SanityDocumentValue<SerializedAPISymbol>

/** @public */
export declare interface APIToken {
  _type: 'api.token'
  member?: APIMember & {
    _id: string
  }
  text: string
}

/** @public */
export declare interface APITypeAlias {
  _id?: string
  _type: 'api.typeAlias'
  comment?: TSDocComment
  export: APIExport
  name: string
  package: APIPackage
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
  type: SanityArrayItem<APIToken>[]
  typeParameters: SanityArrayItem<APITypeParameter>[]
}

/** @public */
export declare interface APITypeParameter {
  _type: 'api.typeParameter'
  constraintType?: SanityArrayItem<APIToken>[]
  defaultType: SanityArrayItem<APIToken>[]
  name: string
}

/** @public */
export declare interface APIVariable {
  _id?: string
  _type: 'api.variable'
  comment?: TSDocComment
  export: APIExport
  isReactComponentType: boolean
  name: string
  package: APIPackage
  propsType?: APIMember
  release: APIRelease
  releaseTag?: APIReleaseTag
  slug: SanitySlugValue
  type: SanityArrayItem<APIToken>[]
}

/** @public */
export declare function defineConfig(config: SanityTSDocConfigOptions): SanityTSDocConfigOptions

/**
 * Extract API information
 *
 * @public
 */
export declare function extract(options: {
  customTags?: TSDocCustomTag[]
  packagePath: string
  rules?: NonNullable<PkgConfigOptions['extract']>['rules']
  strict: boolean
  tsconfig?: string
  bundledPackages?: string[]
}): Promise<{
  pkg: PackageJSON
  results: ExtractResult[]
}>

export {ExtractorLogLevel}

export {ExtractorMessage}

/**
 * @public
 */
export declare interface ExtractResult {
  apiPackage?: ApiPackage
  exportPath: string
  messages: ExtractorMessage[]
  succeeded: boolean
  tempDirPath: string
  typesPath: string
}

/** @internal */
export declare function _fileExists(file: string): boolean

/** @internal */
export declare function _findConfigFile(options: {packagePath: string}): string | undefined

/**
 * @internal
 */
export declare type _FIXME = any

/**
 * @public
 */
export declare function load(
  transformed: APIDocument[],
  opts: {
    cwd: string
    fs?: {
      path: string
    }
    sanity?: {
      projectId?: string
      dataset?: string
      token?: string
    }
  },
): Promise<void>

/** @internal */
export declare function _loadConfig(options: {
  packagePath: string
}): Promise<SanityTSDocConfigOptions | undefined>

/**
 * @public
 */
export declare interface PortableTextBlockNode {
  _type: 'block'
  style: string
  children: SanityArrayItem<PortableTextNode>[]
  markDefs: SanityArrayItem<PortableTextSpanNode['_markDef']>[]
}

/**
 * @public
 */
export declare interface PortableTextCodeNode {
  _type: 'code'
  code: string
  language: string
}

/**
 * @public
 */
export declare type PortableTextNode =
  | PortableTextSpanNode
  | PortableTextCodeNode
  | PortableTextBlockNode

/**
 * @public
 */
export declare interface PortableTextSpanNode {
  _type: 'span'
  _markDef?: {
    _key?: string
    _type: 'link'
    href: string
  }
  marks?: string[]
  text: string
}

/** @internal */
export declare function _printExtractMessages(cwd: string, messages: ExtractorMessage[]): void

/** @public */
export declare type SanityArrayItem<T> = T & {
  _key: string
}

/** @public */
export declare type SanityDocumentValue<T extends {}> = T & {
  _type: string
  _id: string
  _rev?: string
  _updatedAt?: string
  _createdAt?: string
}

/** @public */
export declare interface SanityReferenceValue {
  _type: 'reference'
  _ref: string
  _weak?: boolean
}

/** @public */
export declare interface SanitySlugValue {
  _type: 'slug'
  current: string
}

/** @public */
export declare interface SanityTSDocConfigOptions {
  app?: {
    alias?: Record<string, string>
    port?: number
  }
  extract?: PkgConfigOptions['extract']
  input?: {
    type: 'fs'
    pattern?: string | string[]
    tsconfig?: string
    bundledPackages?: string[]
  }
  output?: {
    fs?: {
      outDir?: string
    }
    sanity?: {
      projectId?: string
      dataset?: string
      token?: string
    }
  }
}

/** @public */
export declare interface SerializedAPICallSignature
  extends Omit<APICallSignature, 'parameters' | 'returnType' | 'typeParameters'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  returnType: SanityArrayItem<SerializedAPIToken>[]
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare interface SerializedAPIClass
  extends Omit<APIClass, 'export' | 'members' | 'package' | 'release' | 'typeParameters'> {
  export: SanityReferenceValue
  members: SanityArrayItem<SerializedAPIClassMember>[]
  package: SanityReferenceValue
  release: SanityReferenceValue
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare type SerializedAPIClassMember =
  | SerializedAPIConstructor
  | SerializedAPIPropertyMember
  | SerializedAPIMethodMember

/** @public */
export declare interface SerializedAPIConstructor extends Omit<APIConstructor, 'parameters'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
}

/** @public */
export declare interface SerializedAPIConstructSignature
  extends Omit<APIConstructSignature, 'parameters' | 'returnType' | 'typeParameters'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  returnType: SanityArrayItem<SerializedAPIToken>[]
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare interface SerializedAPIEnum extends Omit<APIEnum, 'export' | 'package' | 'release'> {
  export: SanityReferenceValue
  package: SanityReferenceValue
  release: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPIExport
  extends Omit<APIExport, 'exports' | 'members' | 'package' | 'release'> {
  members: SanityArrayItem<SanityReferenceValue>[]
  package: SanityReferenceValue
  release: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPIFunction
  extends Omit<
    APIFunction,
    'export' | 'package' | 'parameters' | 'propsType' | 'release' | 'returnType' | 'typeParameters'
  > {
  export: SanityReferenceValue
  package: SanityReferenceValue
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  propsType?: SanityReferenceValue
  release: SanityReferenceValue
  returnType: SanityArrayItem<SerializedAPIToken>[]
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
  /**
   * Used to store if the function is overloading another function
   */
  isOverloading: boolean
}

/** @public */
export declare interface SerializedAPIIndexSignature
  extends Omit<APIIndexSignature, 'parameters' | 'returnType'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  returnType: SanityArrayItem<SerializedAPIToken>[]
}

/** @public */
export declare interface SerializedAPIInterface
  extends Omit<
    APIInterface,
    'export' | 'extends' | 'members' | 'package' | 'release' | 'typeParameters'
  > {
  _type: 'api.interface'
  export: SanityReferenceValue
  extends: {
    _type: 'api.extend'
    type: SanityArrayItem<SerializedAPIToken>[]
  }[]
  members: SanityArrayItem<SerializedAPIInterfaceMember>[]
  package: SanityReferenceValue
  release: SanityReferenceValue
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare type SerializedAPIInterfaceMember =
  | SerializedAPICallSignature
  | SerializedAPIConstructSignature
  | SerializedAPIMethodSignature
  | SerializedAPIPropertySignature
  | SerializedAPIIndexSignature

/**
 * All API member types.
 *
 * @public
 */
export declare type SerializedAPIMember =
  | SerializedAPIClass
  | SerializedAPIEnum
  | SerializedAPIFunction
  | SerializedAPIInterface
  | SerializedAPINamespace
  | SerializedAPITypeAlias
  | SerializedAPIVariable

/** @public */
export declare interface SerializedAPIMethodMember
  extends Omit<APIMethod, 'parameters' | 'returnType' | 'typeParameters'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  returnType: SanityArrayItem<SerializedAPIToken>[]
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare interface SerializedAPIMethodSignature
  extends Omit<APIMethodSignature, 'parameters' | 'returnType' | 'typeParameters'> {
  parameters: SanityArrayItem<SerializedAPIParameter>[]
  returnType: SanityArrayItem<SerializedAPIToken>[]
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare interface SerializedAPINamespace
  extends Omit<APINamespace, 'export' | 'members' | 'package' | 'release'> {
  export: SanityReferenceValue
  members: SanityArrayItem<SerializedAPIMember>[]
  package: SanityReferenceValue
  release: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPIPackage
  extends Omit<APIPackage, 'latestRelease' | 'releases'> {
  latestRelease: SanityReferenceValue
  releases: SanityArrayItem<SanityReferenceValue>[]
}

/** @public */
export declare interface SerializedAPIParameter extends Omit<APIParameter, 'type'> {
  type: SanityArrayItem<SerializedAPIToken>[]
}

/** @public */
export declare interface SerializedAPIPropertyMember extends Omit<APIProperty, 'type'> {
  type: SanityArrayItem<SerializedAPIToken>[]
}

/** @public */
export declare interface SerializedAPIPropertySignature extends Omit<APIPropertySignature, 'type'> {
  type: SanityArrayItem<SerializedAPIToken>[]
}

/** @public */
export declare interface SerializedAPIRelease extends Omit<APIRelease, 'exports' | 'package'> {
  exports: SanityArrayItem<SanityReferenceValue>[]
  package: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPISymbol extends Omit<APISymbol, 'package'> {
  package: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPIToken extends Omit<APIToken, 'member'> {
  member?: SanityReferenceValue
}

/** @public */
export declare interface SerializedAPITypeAlias
  extends Omit<APITypeAlias, 'export' | 'package' | 'release' | 'type' | 'typeParameters'> {
  export: SanityReferenceValue
  type: SanityArrayItem<SerializedAPIToken>[]
  package: SanityReferenceValue
  release: SanityReferenceValue
  typeParameters: SanityArrayItem<SerializedAPITypeParameter>[]
}

/** @public */
export declare interface SerializedAPITypeParameter
  extends Omit<APITypeParameter, 'constraintType' | 'defaultType'> {
  constraintType?: SanityArrayItem<SerializedAPIToken>[]
  defaultType: SanityArrayItem<SerializedAPIToken>[]
}

/** @public */
export declare interface SerializedAPIVariable
  extends Omit<APIVariable, 'export' | 'package' | 'propsType' | 'release' | 'type'> {
  export: SanityReferenceValue
  type: SanityArrayItem<SerializedAPIToken>[]
  package: SanityReferenceValue
  propsType?: SanityReferenceValue
  release: SanityReferenceValue
}

/** @public */
export declare function transform(
  extractResults: ExtractResult[],
  opts: TransformOpts,
): APIDocument[]

/**
 * @public
 */
export declare interface TransformContext {
  apiPackage: ApiPackage
  scope?: string
  name: string
  version: string
  package?: APIPackageDocument
  release?: APIReleaseDocument
  export: APIExportDocument
}

/**
 * @public
 */
export declare interface TransformOpts {
  package: {
    version: string
  }
  currPackageDoc?: APIPackageDocument
}

/** @public */
export declare interface TSDocComment {
  _type: 'tsdoc.docComment'
  customBlocks?: SanityArrayItem<TSDocCustomBlock>[]
  deprecated?: TSDocDeprecatedBlock
  exampleBlocks?: SanityArrayItem<TSDocExampleBlock>[]
  modifierTags?: SanityArrayItem<TSDocModifierTag>[]
  parameters?: SanityArrayItem<TSDocParamBlock>[]
  remarks?: TSDocRemarksBlock
  returns?: TSDocReturnsBlock
  seeBlocks?: SanityArrayItem<TSDocSeeBlock>[]
  summary?: SanityArrayItem<PortableTextNode>[]
}

/** @public */
export declare interface TSDocCustomBlock {
  _type: 'tsdoc.customBlock'
  content?: PortableTextNode[]
  tag: string
}

/**
 * @public
 */
export declare interface TSDocCustomTag {
  name: string
  syntaxKind: 'block' | 'modifier'
  allowMultiple?: boolean
}

/** @public */
export declare interface TSDocDeprecatedBlock {
  _type: 'tsdoc.deprecatedBlock'
  content?: PortableTextNode[]
}

/** @public */
export declare interface TSDocExampleBlock {
  _type: 'tsdoc.exampleBlock'
  content?: PortableTextNode[]
}

/** @public */
export declare interface TSDocModifierTag {
  _type: 'tsdoc.modifierTag'
  name: string
}

/** @public */
export declare interface TSDocParamBlock {
  _type: 'tsdoc.paramBlock'
  content?: PortableTextNode[]
  name: string
}

/** @public */
export declare interface TSDocRemarksBlock {
  _type: 'tsdoc.remarksBlock'
  content?: PortableTextNode[]
}

/** @public */
export declare interface TSDocReturnsBlock {
  _type: 'tsdoc.returnsBlock'
  content?: PortableTextNode[]
}

/** @public */
export declare interface TSDocSeeBlock {
  _type: 'tsdoc.seeBlock'
  content?: PortableTextNode[]
}

export {}
