/* eslint-disable @typescript-eslint/no-empty-object-type */
import { IApiDomainProperty } from './Base.js'
import { IApiDataExample, IApiDataNode, IApiDataNodeUnion, IShapeUnion } from './Shapes.js'

export type IScalarDataTypes =
  | 'string'
  | 'base64Binary'
  | 'boolean'
  | 'date'
  | 'dateTime'
  | 'double'
  | 'float'
  | 'integer'
  | 'long'
  | 'number'
  | 'time'

export interface IApiSummary extends IApiDomainProperty {
  name?: string
  description?: string
  // identifier?: string; <- not sure what this is.
  schemes: string[]
  accepts: string[]
  contentType: string[]
  version?: string
  termsOfService?: string
  provider?: IApiOrganization
  license?: IApiLicense
  documentations: IApiDocumentation[]
  tags: IApiTag[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiBase extends IApiSummary {
  endPoints: IApiEndPoint[]
  servers: IApiServer[]
  security: IApiSecurityRequirement[]
}

export interface IApiWeb extends IApiBase {}
export interface IApiAsync extends IApiBase {}

export interface IApiOrganization extends IApiDomainProperty {
  url?: string
  name?: string
  email?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiLicense extends IApiDomainProperty {
  url?: string
  name?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiEndPoint extends IApiDomainProperty {
  description?: string
  name?: string
  summary?: string
  path: string
  operations: IApiOperation[]
  parameters: IApiParameter[]
  payloads: IApiPayload[]
  servers: IApiServer[]
  security: IApiSecurityRequirement[]
  sourceMaps?: IApiDocumentSourceMaps
  extends: IApiParametrizedDeclaration[]
}

export interface IApiOperation extends IApiDomainProperty {
  method: string
  name?: string
  description?: string
  summary?: string
  deprecated: boolean
  schemes?: string[]
  accepts?: string[]
  contentType?: string[]
  operationId?: string
  documentation?: IApiDocumentation
  request?: IApiRequest
  responses: IApiResponse[]
  security: IApiSecurityRequirement[]
  callbacks: IApiCallback[]
  servers: IApiServer[]
  tags: IApiTag[]
  sourceMaps?: IApiDocumentSourceMaps
  extends: IApiParametrizedTrait[]
}

export interface IApiTag extends IApiDomainProperty {
  name: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiServer extends IApiDomainProperty {
  url: string
  description?: string
  variables: IApiParameter[]
  sourceMaps?: IApiDocumentSourceMaps
  protocol?: string
  protocolVersion?: string
  security?: IApiSecurityRequirement[]
}

export interface IApiParameter extends IApiDomainProperty {
  name?: string
  paramName?: string
  description?: string
  required?: boolean
  deprecated?: boolean
  allowEmptyValue?: boolean
  style?: string
  explode?: boolean
  allowReserved?: boolean
  binding?: string
  schema?: IShapeUnion
  payloads: IApiPayload[]
  examples: IApiDataExample[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiPayload extends IApiDomainProperty {
  name?: string
  mediaType?: string
  schema?: IShapeUnion
  examples: IApiDataExample[]
  // encoding: ApiEncoding[];
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiResponse extends IApiDomainProperty {
  name?: string
  description?: string
  statusCode?: string
  headers: IApiParameter[]
  payloads: IApiPayload[]
  examples: IApiDataExample[]
  links: IApiTemplatedLink[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiTemplatedLink extends IApiDomainProperty {
  name?: string
  description?: string
  template?: string
  operationId?: string
  requestBody?: string
  mapping: IApiIriTemplateMapping[]
  server?: IApiServer
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiIriTemplateMapping extends IApiDomainProperty {
  templateVariable?: string
  linkExpression?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityRequirement extends IApiDomainProperty {
  name?: string
  schemes: IApiParametrizedSecurityScheme[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiParametrizedSecurityScheme extends IApiDomainProperty {
  name?: string
  settings?: IApiSecuritySettingsUnion
  scheme?: IApiSecurityScheme
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityScheme extends IApiDomainProperty {
  name?: string
  type?: string
  displayName?: string
  description?: string
  settings?: IApiSecuritySettingsUnion
  headers: IApiParameter[]
  queryParameters: IApiParameter[]
  responses: IApiResponse[]
  queryString?: IShapeUnion
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecuritySettings extends IApiDomainProperty {
  additionalProperties?: IApiDataNodeUnion
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityOAuth1Settings extends IApiSecuritySettings {
  requestTokenUri?: string
  authorizationUri?: string
  tokenCredentialsUri?: string
  signatures: string[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityOAuth2Settings extends IApiSecuritySettings {
  authorizationGrants: string[]
  flows: IApiSecurityOAuth2Flow[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityApiKeySettings extends IApiSecuritySettings {
  name?: string
  in?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityHttpSettings extends IApiSecuritySettings {
  scheme?: string
  bearerFormat?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityOpenIdConnectSettings extends IApiSecuritySettings {
  url?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export type IApiSecuritySettingsUnion =
  | IApiSecuritySettings
  | IApiSecurityOAuth1Settings
  | IApiSecurityOAuth2Settings
  | IApiSecurityApiKeySettings
  | IApiSecurityHttpSettings
  | IApiSecurityOpenIdConnectSettings

export interface IApiSecurityOAuth2Flow extends IApiDomainProperty {
  authorizationUri?: string
  accessTokenUri?: string
  flow?: string
  refreshUri?: string
  scopes: IApiSecurityScope[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiSecurityScope extends IApiDomainProperty {
  name?: string
  description?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiRequest extends IApiDomainProperty {
  description?: string
  required?: boolean
  queryParameters: IApiParameter[]
  headers: IApiParameter[]
  payloads: IApiPayload[]
  queryString?: IShapeUnion
  uriParameters: IApiParameter[]
  cookieParameters: IApiParameter[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiCallback extends IApiDomainProperty {
  name?: string
  expression?: string
  endpoint?: IApiEndPoint
  sourceMaps?: IApiDocumentSourceMaps
}

/**
 * The definition of the domain extension
 */
export interface IApiCustomDomainExtension extends IApiDomainProperty {
  name?: string
  displayName?: string
  description?: string
  domain: string[]
  schema?: IShapeUnion
  sourceMaps?: IApiDocumentSourceMaps
}

/**
 * Applies to an object domain extension
 */
export interface IApiDomainExtension extends IApiDomainProperty {
  name?: string
  definedBy?: IApiCustomDomainExtension
  extension?: IApiDataNodeUnion
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiDocumentation extends IApiDomainProperty {
  url?: string
  description?: string
  title?: string
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiEncoding {
  propertyName?: string
  contentType?: string
  style?: string
  explode?: boolean
  allowReserved?: boolean
  headers: IApiParameter[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiDocumentSourceMaps {
  id?: string
  types?: string[]
  synthesizedField?: IApiSynthesizedField[]
  lexical?: IApiSynthesizedField[]
  trackedElement?: IApiSynthesizedField
  autoGeneratedName?: IApiSynthesizedField[]
  parsedJsonSchema?: IApiSynthesizedField
  declaredElement?: IApiSynthesizedField
}

export interface IApiSynthesizedField {
  id: string
  element?: string
  value: string
}

export interface IApiParametrizedDeclaration extends IApiDomainProperty {
  name?: string
  target?: IApiAbstractDeclaration
  variables: IApiVariableValue[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiVariableValue extends IApiDomainProperty {
  name: string
  value?: IApiDataNode
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiAbstractDeclaration extends IApiDomainProperty {
  name: string
  description?: string
  dataNode?: IApiDataNode
  variables: string[]
  sourceMaps?: IApiDocumentSourceMaps
}

export interface IApiParametrizedTrait extends IApiParametrizedDeclaration {}
export interface IApiParametrizedResourceType extends IApiParametrizedDeclaration {}

export interface IShapeProcessingOptions {
  /**
   * This is set when serializing a shape / parameter.
   * It is used to determine which example of the schema to include.
   *
   * When an example has the `tracked-element` in the source maps then this
   * is used to determine the only examples included to the schema.
   *
   * Note, the value of the tracked-element can be a list of IDs separated by coma.
   */
  trackedId?: string
}

/**
 * The selected type
 *
 * - `server`: server from the AMF model
 * - `custom`: custom base URI value (entered by the user)
 * - `extra`: an application controlled server value selected by the user.
 */
export type IServerType = 'server' | 'custom' | 'extra'
export type ISelectionType = 'summary' | 'resource' | 'operation' | 'schema' | 'security' | 'documentation'
/**
 * API navigation layout options.
 *
 * - tree - creates a tree structure from the endpoints list
 * - natural - behavior consistent with the previous version of the navigation.
 *             Creates a tree structure based on the previous endpoints.
 * - natural-sort - as `natural` but endpoints are sorted by name.
 * - off (or none) - just like in the API spec.
 */
export type INavigationLayout = 'tree' | 'natural' | 'natural-sort' | 'off'

export interface ISelectableMenuItem {
  /**
   * Whether the item is a selected menu item.
   */
  selected?: boolean
  /**
   * Whether the item has secondary selection.
   * This happens when a "passive" selection has been applied to the item.
   */
  secondarySelected?: boolean
}

export interface IEditableMenuItem {
  /**
   * When set the name editor for the item is enabled.
   */
  nameEditor?: boolean
}

export interface IApiEndPointListItem {
  /**
   * The domain id of the endpoint.
   * It may be undefined when the endpoint is created "abstract" endpoint vor the visualization.
   */
  id?: string
  path: string
  name?: string
}

export interface IApiEndPointWithOperationsListItem extends IApiEndPointListItem {
  operations: IApiOperationListItem[]
}

export interface IApiOperationListItem {
  id: string
  method: string
  name?: string
}

export interface IApiEndpointsTreeItem extends IApiEndPointWithOperationsListItem {
  label: string
  indent: number
  hasShortPath?: boolean
  hasChildren?: boolean
}

export interface IApiSecuritySchemeListItem {
  id: string
  type: string
  name?: string
  displayName?: string
  types: string[]
}

export declare interface IApiNodeShapeListItem {
  id: string
  name?: string
  displayName?: string
}

export interface IEndpointItem extends IApiEndpointsTreeItem, ISelectableMenuItem, IEditableMenuItem {
  operations: IOperationItem[]
}

export interface IOperationItem extends IApiOperationListItem, ISelectableMenuItem, IEditableMenuItem {}
export interface INodeShapeItem extends IApiNodeShapeListItem, ISelectableMenuItem, IEditableMenuItem {}
export interface ISecurityItem extends IApiSecuritySchemeListItem, ISelectableMenuItem {}
export interface IDocumentationItem extends IApiDocumentation, ISelectableMenuItem, IEditableMenuItem {}
export type ISchemaAddType = 'scalar' | 'object' | 'file' | 'array' | 'union'
