import type { AppliedDataSemantic } from '../Semantics.js'
import { SemanticType } from '../Semantics.js'

/**
 * Configuration options for the Tags semantic.
 * Controls allowed tags, validation, and formatting for associations.
 */
export interface TagsConfig {
  /**
   * List of allowed tags.
   */
  allowedTags?: string[]
  /**
   * Whether to allow custom tags not in the allowedTags list.
   */
  allowCustomTags?: boolean
  /**
   * Whether tags are case sensitive.
   */
  caseSensitive?: boolean
  /**
   * Whether to allow Unicode characters in tags.
   */
  allowUnicode?: boolean
  /**
   * Custom metadata for the tags association.
   */
  metadata?: Record<string, unknown>
  /**
   * Index signature to allow additional properties.
   */
  [key: string]: unknown
}

/**
 * Type-safe configuration for Tags semantic.
 */
export interface AppliedTagsSemantic extends AppliedDataSemantic {
  id: SemanticType.Tags
  config?: TagsConfig
}

/**
 * Type guard to check if a semantic is a Tags semantic.
 */
export const isTagsSemantic = (semantic: AppliedDataSemantic): semantic is AppliedTagsSemantic => {
  return semantic.id === SemanticType.Tags
}

/**
 * Helper function to create a Tags semantic with configuration.
 */
export const createTagsSemantic = (config: TagsConfig = {}): AppliedTagsSemantic => {
  const mergedConfig = {
    ...DEFAULT_TAGS_CONFIG,
    ...config,
  }
  if (config.metadata) {
    mergedConfig.metadata = { ...config.metadata }
  }

  return {
    id: SemanticType.Tags,
    config: mergedConfig,
  }
}

/**
 * Default configuration for Tags semantic.
 */
export const DEFAULT_TAGS_CONFIG: TagsConfig = {
  allowCustomTags: true,
  caseSensitive: false,
  allowUnicode: false,
}
