import {AssetSource} from '@sanity/types'
import {FieldDefinitionBase} from '@sanity/types'
import {InitialValueProperty} from '@sanity/types'
import {ObjectDefinition} from '@sanity/types'
import {ObjectOptions} from '@sanity/types'
import {PreviewConfig} from '@sanity/types'
import {Reference} from '@sanity/types'
import {RuleDef} from '@sanity/types'
import {ValidationBuilder} from '@sanity/types'
import {WidenInitialValue} from '@sanity/types'
import {WidenValidation} from '@sanity/types'

/**
 * Define a video field within a document, object, image or file definition `fields` array.
 *
 * This function will narrow the schema type down to video fields and options based on the provided
 * type-string.
 *
 * Using `defineVideoField` is optional, but should provide improved autocompletion in your IDE, when building your schema.
 * Video field-properties like `validation` and `initialValue` will also be more specific.
 *
 * Note: This video field type is designed to work specifically with the Media Library asset source.
 * Make sure you have the Media Library is enabled in your studio via sanity.config.ts.
 *
 * See {@link defineType} for similar examples.
 *
 * @param definition - should be a valid video field type definition.
 *
 * @see defineField
 * @see defineArrayMember
 * @see typed
 *
 * @beta
 */
export declare function defineVideoField(
  definition: Omit<VideoDefinition, 'type'> & FieldDefinitionBase,
): {
  type: 'sanity.video'
  name: string
} & Omit<VideoDefinition_2, 'preview'> & {
    preview?: PreviewConfig<Record<string, string>, Record<string, any>> | undefined
  } & FieldDefinitionBase &
  WidenValidation &
  WidenInitialValue

/** @public */
declare interface VideoDefinition extends Omit<
  ObjectDefinition,
  'type' | 'fields' | 'options' | 'groups' | 'validation'
> {
  type: 'sanity.video'
  fields?: ObjectDefinition['fields']
  options?: VideoOptions
  validation?: ValidationBuilder<VideoRule, VideoValue>
  initialValue?: InitialValueProperty<any, VideoValue>
}

/**
 * @public
 * @beta
 */
declare interface VideoDefinition_2 extends Omit<ObjectDefinition, 'type' | 'fields' | 'options'> {
  type: typeof videoTypeName
  options?: VideoOptions
}

/** @public */
declare interface VideoOptions extends ObjectOptions {
  accept?: string
  sources?: AssetSource[]
}

/** @public */
declare interface VideoRule extends RuleDef<VideoRule, VideoValue> {
  /**
   * Require a file field has an asset.
   *
   * @example
   * ```ts
   * defineField({
   *  name: 'video',
   *  title: 'Video',
   *  type: 'sanity.video',
   *  validation: (Rule) => Rule.required().assetRequired(),
   * })
   * ```
   */
  assetRequired(): VideoRule
}

/**
 * @public
 * @beta
 */
declare const videoTypeName: 'sanity.video'

/** @public */
declare interface VideoValue {
  asset?: Reference
  media?: Reference
  [index: string]: unknown
}

export {}

declare module '@sanity/types' {
  interface IntrinsicDefinitions {
    'sanity.video': VideoDefinition
  }
}
