import type { OpenAPI, OpenAPIV3, OpenAPIV3_1 } from '@scalar/openapi-types'
import type { RemovableRef } from '@vueuse/core'

/**
 * Slots required for OAOperation component.
 */
export type OperationSlot
  = | 'header'
    | 'tags'
    | 'path'
    | 'description'
    | 'security'
    | 'parameters'
    | 'request-body'
    | 'responses'
    | 'playground'
    | 'try-it' // @deprecated. TODO: Remove this slot.
    | 'code-samples'
    | 'branding'
    | 'footer'
// TODO: Implement these slots.
// | 'summary'
// | 'servers'

export type OpenAPIDocument = OpenAPIV3.Document & OpenAPIV3_1.Document

export type ParsedPaths = OpenAPIV3.PathsObject & OpenAPIV3_1.PathsObject & {
  [key: string]: OpenAPIV3.PathItemObject & OpenAPIV3_1.PathItemObject & {
    [key: string]: ParsedOperation
  }
}

export type ParsedOpenAPI = OpenAPIDocument & {
  paths: ParsedPaths
}

export type OARequestBody = OpenAPIV3.RequestBodyObject & OpenAPIV3_1.RequestBodyObject & {
  content: {
    [key: string]: ParsedContent
  }
}

export type ParsedOperation = OpenAPIV3.OperationObject & OpenAPIV3_1.OperationObject & {
  operationId: string
  security?: OpenAPIV3.SecurityRequirementObject[] & OpenAPIV3_1.SecurityRequirementObject[] & {
    [key: string]: string[]
  }
  securityUi?: SecurityUi
  requestBody: OARequestBody
  responses: OpenAPIV3.ResponsesObject & OpenAPIV3_1.ResponsesObject & {
    [key: string]: OpenAPIV3.ResponseObject & OpenAPIV3_1.ResponseObject & {
      content: {
        [key: string]: ParsedContent
      }
    }
  }
}

export type ParsedContent = OpenAPIV3.MediaTypeObject & OpenAPIV3_1.MediaTypeObject & {
  schema: OpenAPIV3.SchemaObject & OpenAPIV3_1.SchemaObject
  ui?: any
  examples?: {
    [key: string]: OAExampleObject
  }
}

export type OperationObject = OpenAPIV3.Document | OpenAPIV3_1.OperationObject

export type AllSecuritySchemes = OpenAPIV3.HttpSecurityScheme & OpenAPIV3.ApiKeySecurityScheme & OpenAPIV3.OAuth2SecurityScheme & OpenAPIV3.OpenIdSecurityScheme

export type PlaygroundSecurityScheme = AllSecuritySchemes & {
  value: string | RemovableRef<any>
  label: string
  name: string
  example?: string
}

export interface SecurityUi extends Array<SecurityUiItem> {}

export interface SecurityUiItem {
  id: string
  schemes: {
    [key: string]: OpenAPIV3.SecuritySchemeObject
  }
}

export type OAExampleObject = OpenAPI.ExampleObject & {
  isAutogenerated?: boolean
  lang?: string
  hideOnSchemaTabs?: boolean
}

export interface PathsGroupView {
  name: string
  paths: Record<string, OpenAPIV3.PathItemObject & OpenAPIV3_1.PathItemObject>
  isOpen: boolean
  description?: string
  isGrouped: boolean
}
