/**
 * GraphQL Types for Brainfish API Documentation
 * 
 * Types for parsing and representing GraphQL schemas in the documentation system.
 */

// ============================================================================
// GraphQL Scalar Types
// ============================================================================

export type GraphQLScalarType = 
  | 'String'
  | 'Int'
  | 'Float'
  | 'Boolean'
  | 'ID'
  | string // Custom scalars

// ============================================================================
// GraphQL Type Kinds
// ============================================================================

export type GraphQLTypeKind = 
  | 'SCALAR'
  | 'OBJECT'
  | 'INPUT_OBJECT'
  | 'ENUM'
  | 'INTERFACE'
  | 'UNION'
  | 'LIST'
  | 'NON_NULL'

// ============================================================================
// GraphQL Type Reference
// ============================================================================

export interface GraphQLTypeRef {
  kind: GraphQLTypeKind
  name: string | null
  ofType?: GraphQLTypeRef | null
}

// ============================================================================
// GraphQL Argument
// ============================================================================

export interface GraphQLArgument {
  name: string
  description: string | null
  type: GraphQLTypeRef
  defaultValue: string | null
  isRequired: boolean
}

// ============================================================================
// GraphQL Field
// ============================================================================

export interface GraphQLField {
  name: string
  description: string | null
  args: GraphQLArgument[]
  type: GraphQLTypeRef
  isDeprecated: boolean
  deprecationReason: string | null
}

// ============================================================================
// GraphQL Enum Value
// ============================================================================

export interface GraphQLEnumValue {
  name: string
  description: string | null
  isDeprecated: boolean
  deprecationReason: string | null
}

// ============================================================================
// GraphQL Input Field
// ============================================================================

export interface GraphQLInputField {
  name: string
  description: string | null
  type: GraphQLTypeRef
  defaultValue: string | null
  isRequired: boolean
}

// ============================================================================
// GraphQL Type Definitions
// ============================================================================

export interface GraphQLScalarTypeDef {
  kind: 'SCALAR'
  name: string
  description: string | null
}

export interface GraphQLObjectTypeDef {
  kind: 'OBJECT'
  name: string
  description: string | null
  fields: GraphQLField[]
  interfaces: string[]
}

export interface GraphQLInputObjectTypeDef {
  kind: 'INPUT_OBJECT'
  name: string
  description: string | null
  inputFields: GraphQLInputField[]
}

export interface GraphQLEnumTypeDef {
  kind: 'ENUM'
  name: string
  description: string | null
  enumValues: GraphQLEnumValue[]
}

export interface GraphQLInterfaceTypeDef {
  kind: 'INTERFACE'
  name: string
  description: string | null
  fields: GraphQLField[]
  possibleTypes: string[]
}

export interface GraphQLUnionTypeDef {
  kind: 'UNION'
  name: string
  description: string | null
  possibleTypes: string[]
}

export type GraphQLTypeDef = 
  | GraphQLScalarTypeDef
  | GraphQLObjectTypeDef
  | GraphQLInputObjectTypeDef
  | GraphQLEnumTypeDef
  | GraphQLInterfaceTypeDef
  | GraphQLUnionTypeDef

// ============================================================================
// GraphQL Operation Types
// ============================================================================

export type GraphQLOperationType = 'query' | 'mutation' | 'subscription'

export interface GraphQLOperation {
  id: string
  name: string
  description: string | null
  operationType: GraphQLOperationType
  args: GraphQLArgument[]
  returnType: GraphQLTypeRef
  isDeprecated: boolean
  deprecationReason: string | null
}

// ============================================================================
// GraphQL Directive
// ============================================================================

export interface GraphQLDirective {
  name: string
  description: string | null
  locations: string[]
  args: GraphQLArgument[]
}

// ============================================================================
// GraphQL Schema
// ============================================================================

export interface GraphQLSchemaInfo {
  /** Schema description */
  description: string | null
  /** Query type name (usually "Query") */
  queryType: string | null
  /** Mutation type name (usually "Mutation") */
  mutationType: string | null
  /** Subscription type name (usually "Subscription") */
  subscriptionType: string | null
}

export interface GraphQLSchema {
  /** Schema metadata */
  info: GraphQLSchemaInfo
  /** All type definitions */
  types: Record<string, GraphQLTypeDef>
  /** All directives */
  directives: GraphQLDirective[]
  /** Parsed queries */
  queries: GraphQLOperation[]
  /** Parsed mutations */
  mutations: GraphQLOperation[]
  /** Parsed subscriptions */
  subscriptions: GraphQLOperation[]
}

// ============================================================================
// GraphQL Collection (for integration with existing system)
// ============================================================================

export interface BrainfishGraphQLRequest {
  id: string
  name: string
  description: string | null
  operationType: GraphQLOperationType
  /** The GraphQL query/mutation/subscription string */
  query: string
  /** Variables schema */
  variables: GraphQLArgument[]
  /** Return type */
  returnType: GraphQLTypeRef
  /** Tags for grouping */
  tags: string[]
  /** Example variables */
  exampleVariables?: Record<string, unknown>
  /** Example response */
  exampleResponse?: unknown
}

export interface BrainfishGraphQLCollection {
  id: string
  name: string
  description: string | null
  /** GraphQL endpoint URL */
  endpoint: string
  /** Schema information */
  schema: GraphQLSchema
  /** All operations organized */
  queries: BrainfishGraphQLRequest[]
  mutations: BrainfishGraphQLRequest[]
  subscriptions: BrainfishGraphQLRequest[]
  /** Custom types for reference */
  types: GraphQLTypeDef[]
}

// ============================================================================
// Helper Functions
// ============================================================================

/**
 * Format a GraphQL type reference as a string
 * e.g., [String!]! -> "[String!]!"
 */
export function formatTypeRef(typeRef: GraphQLTypeRef): string {
  if (typeRef.kind === 'NON_NULL' && typeRef.ofType) {
    return `${formatTypeRef(typeRef.ofType)}!`
  }
  if (typeRef.kind === 'LIST' && typeRef.ofType) {
    return `[${formatTypeRef(typeRef.ofType)}]`
  }
  return typeRef.name || 'Unknown'
}

/**
 * Check if a type is required (non-null at the top level)
 */
export function isTypeRequired(typeRef: GraphQLTypeRef): boolean {
  return typeRef.kind === 'NON_NULL'
}

/**
 * Get the base type name from a type reference
 */
export function getBaseTypeName(typeRef: GraphQLTypeRef): string {
  if (typeRef.ofType) {
    return getBaseTypeName(typeRef.ofType)
  }
  return typeRef.name || 'Unknown'
}

/**
 * Check if a type is a scalar type
 */
export function isScalarType(typeName: string): boolean {
  return ['String', 'Int', 'Float', 'Boolean', 'ID'].includes(typeName)
}
