import {CachingStrategy} from '@shopify/hydrogen'
import {ClientConfig} from '@sanity/client'
import {createClient} from '@sanity/client'
import {QueryParams} from '@sanity/client'
import {QueryResponseInitial} from '@sanity/react-loader'
import {ResponseQueryOptions} from '@sanity/client'
import {SanityClient} from '@sanity/client'
import {WithCache} from '@shopify/hydrogen'

export {createClient}

/**
 * @public
 */
export declare function createSanityContext(options: CreateSanityContextOptions): SanityContext

declare type CreateSanityContextOptions = {
  request: Request
  cache?: Cache | undefined
  waitUntil?: WaitUntil | undefined
  /**
   * Sanity client or configuration to use.
   */
  client: SanityClient | ClientConfig
  /**
   * The default caching strategy to use for `loadQuery` subrequests.
   * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies
   *
   * Defaults to `CacheLong`
   */
  defaultStrategy?: CachingStrategy | null
  /**
   * Configuration for enabling preview mode.
   */
  preview?: {
    enabled: boolean
    token: string
    studioUrl: string
  }
}

/**
 * @deprecated Use `createSanityContext` instead
 */
export declare function createSanityLoader(options: CreateSanityLoaderOptions): SanityLoader

declare type CreateSanityLoaderOptions = {
  /**
   * Cache control utility from `@shopify/hydrogen`.
   * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching/third-party
   */
  withCache: WithCache
  /**
   * Sanity client or configuration to use.
   */
  client: SanityClient | ClientConfig
  /**
   * The default caching strategy to use for `loadQuery` subrequests.
   * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies
   *
   * Defaults to `CacheLong`
   */
  strategy?: CachingStrategy | null
  /**
   * Configuration for enabling preview mode.
   */
  preview?: {
    enabled: boolean
    token: string
    studioUrl: string
  }
}

declare type HydrogenResponseQueryOptions = Omit<ResponseQueryOptions, 'next' | 'cache'> & {
  hydrogen?: 'hydrogen' extends keyof RequestInit_2 ? RequestInit_2['hydrogen'] : never
}

declare type HydrogenResponseQueryOptions_2 = Omit<ResponseQueryOptions, 'next' | 'cache'> & {
  hydrogen?: 'hydrogen' extends keyof RequestInit_3 ? RequestInit_3['hydrogen'] : never
}

declare type LoadQueryOptions<T> = Pick<
  HydrogenResponseQueryOptions,
  'perspective' | 'hydrogen' | 'useCdn' | 'stega' | 'headers' | 'tag'
> & {
  hydrogen?: {
    /**
     * Whether to cache the result of the query or not.
     * @defaultValue () => true
     */
    shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean
  }
}

declare type LoadQueryOptions_2<T> = Pick<
  HydrogenResponseQueryOptions_2,
  'perspective' | 'hydrogen' | 'useCdn' | 'stega' | 'headers' | 'tag'
> & {
  hydrogen?: {
    /**
     * Whether to cache the result of the query or not.
     * @defaultValue () => true
     */
    shouldCacheResult?: (value: QueryResponseInitial<T>) => boolean
  }
}

declare interface RequestInit_2 {
  hydrogen?: {
    /**
     * The caching strategy to use for the subrequest.
     * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies
     */
    cache?: CachingStrategy
    /**
     * Optional debugging information to be displayed in the subrequest profiler.
     * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request
     */
    debug?: {
      displayName: string
    }
  }
}

declare interface RequestInit_3 {
  hydrogen?: {
    /**
     * The caching strategy to use for the subrequest.
     * @see https://shopify.dev/docs/custom-storefronts/hydrogen/caching#caching-strategies
     */
    cache?: CachingStrategy
    /**
     * Optional debugging information to be displayed in the subrequest profiler.
     * @see https://shopify.dev/docs/custom-storefronts/hydrogen/debugging/subrequest-profiler#how-to-provide-more-debug-information-for-a-request
     */
    debug?: {
      displayName: string
    }
  }
}

export {SanityClient}

export declare type SanityContext = {
  /**
   * Query Sanity using the loader.
   * @see https://www.sanity.io/docs/loaders
   */
  loadQuery<T = any>(
    query: string,
    params?: QueryParams,
    options?: LoadQueryOptions<T>,
  ): Promise<QueryResponseInitial<T>>
  client: SanityClient
  preview?: CreateSanityContextOptions['preview']
}

export declare type SanityLoader = {
  /**
   * Query Sanity using the loader.
   * @see https://www.sanity.io/docs/loaders
   */
  loadQuery<T = any>(
    query: string,
    params?: QueryParams,
    options?: LoadQueryOptions_2<T>,
  ): Promise<QueryResponseInitial<T>>
  client: SanityClient
  preview?: CreateSanityLoaderOptions['preview']
}

declare type WaitUntil = (promise: Promise<unknown>) => void

export * from '@sanity/client'

export {}
