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

/**
 * Configuration options for the Status semantic.
 * These options control state management and workflow behavior.
 */
export interface StatusConfig {
  /**
   * Allowed states for this status field.
   * Only required when the field doesn't have enum values defined in the schema.
   * If enum values are defined in DomainProperty > Schema, those values will be used instead.
   */
  allowedStates?: string[]

  /**
   * Default state when creating new records.
   * Must be one of the allowedStates (if specified) or enum values from the schema.
   */
  defaultState?: string

  /**
   * State transitions configuration.
   * Maps from current state to array of allowed next states.
   */
  transitions?: Record<string, string[]>

  /**
   * State-specific behaviors and permissions.
   */
  stateBehaviors?: Record<
    string,
    {
      /**
       * Whether records in this state are publicly visible.
       * Defaults to true if not specified.
       */
      isPublic?: boolean

      /**
       * Whether records in this state can be edited.
       * Defaults to true if not specified.
       */
      isEditable?: boolean

      /**
       * Whether records in this state can be deleted.
       * Defaults to false if not specified.
       */
      isDeletable?: boolean

      /**
       * Whether this state requires approval before transition.
       * Defaults to false if not specified.
       */
      requiresApproval?: boolean

      /**
       * Custom display name for this state.
       */
      displayName?: string

      /**
       * Custom description for this state.
       */
      description?: string

      /**
       * Color or visual indicator for this state.
       */
      color?: string

      /**
       * Icon for this state.
       */
      icon?: string
    }
  >

  /**
   * Workflow configuration for status management.
   */
  workflow?: {
    /**
     * Whether status changes require approval.
     * Defaults to false if not specified.
     */
    requiresApproval?: boolean

    /**
     * Roles that can approve status changes.
     * Required if requiresApproval is true.
     */
    approvalRoles?: string[]

    /**
     * Whether to send notifications on status changes.
     * Defaults to false if not specified.
     */
    sendNotifications?: boolean

    /**
     * Notification channels to use.
     */
    notificationChannels?: ('email' | 'sms' | 'push' | 'webhook')[]

    /**
     * Whether to log status change history.
     * Defaults to true if not specified.
     */
    logHistory?: boolean

    /**
     * Whether to allow bulk status changes.
     * Defaults to false if not specified.
     */
    allowBulkChanges?: boolean
  }

  /**
   * Auto-transitions based on conditions.
   */
  autoTransitions?: {
    /**
     * Current state that triggers the auto-transition.
     */
    from: string

    /**
     * Target state to transition to.
     */
    to: string

    /**
     * Condition that triggers the transition.
     * Examples: "after 24 hours", "when approved", "when payment received"
     */
    condition: string

    /**
     * Whether this auto-transition requires approval.
     * Defaults to false if not specified.
     */
    requiresApproval?: boolean
  }[]

  /**
   * Custom metadata for the status field.
   */
  metadata?: Record<string, unknown>

  /**
   * Index signature to allow additional properties.
   */
  [key: string]: unknown
}

/**
 * Type-safe configuration for Status semantic.
 */
export interface AppliedStatusSemantic extends AppliedDataSemantic {
  id: SemanticType.Status
  config?: StatusConfig
}

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

/**
 * Helper function to create a Status semantic with configuration.
 */
export const createStatusSemantic = (config: Partial<StatusConfig> = {}): AppliedStatusSemantic => {
  const mergedConfig = {
    ...DEFAULT_STATUS_CONFIG,
    ...config,
    // Deep merge nested objects
    stateBehaviors: config.stateBehaviors
      ? { ...DEFAULT_STATUS_CONFIG.stateBehaviors, ...config.stateBehaviors }
      : DEFAULT_STATUS_CONFIG.stateBehaviors,
    workflow: config.workflow
      ? { ...DEFAULT_STATUS_CONFIG.workflow, ...config.workflow }
      : DEFAULT_STATUS_CONFIG.workflow,
  }

  if (config.metadata) {
    mergedConfig.metadata = { ...config.metadata }
  }

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

/**
 * Default configuration for Status semantic.
 */
export const DEFAULT_STATUS_CONFIG: StatusConfig = {
  allowedStates: ['draft', 'published', 'archived'],
  defaultState: 'draft',
  stateBehaviors: {
    draft: {
      isPublic: false,
      isEditable: true,
      isDeletable: true,
    },
    published: {
      isPublic: true,
      isEditable: true,
      isDeletable: false,
    },
    archived: {
      isPublic: false,
      isEditable: false,
      isDeletable: false,
    },
  },
  workflow: {
    requiresApproval: false,
    sendNotifications: false,
    logHistory: true,
    allowBulkChanges: false,
  },
}
