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 ParsedOpenAPI = OpenAPIDocument & {
  paths: OpenAPIV3.PathsObject & OpenAPIV3_1.PathsObject & {
    [key: string]: OpenAPIV3.PathItemObject & OpenAPIV3_1.PathItemObject & {
      [key: string]: ParsedOperation
    }
  }
}

export type ParsedOperation = OpenAPIV3.OperationObject & OpenAPIV3_1.OperationObject & {
  operationId: string
  security?: OpenAPIV3.SecurityRequirementObject[] & OpenAPIV3_1.SecurityRequirementObject[] & {
    [key: string]: string[]
  }
  securityUi?: SecurityUi
  requestBody: OpenAPIV3.RequestBodyObject & OpenAPIV3_1.RequestBodyObject & {
    content: ParsedContent
  }
  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
}

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
}

export interface SecurityUi extends Array<SecurityUiItem> {}

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

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

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