import { IKosDataModel } from '../../../core';
import { FutureResponse } from '../../../services/future';
import { FutureContainer, IFutureModel } from '../../future/future-types';
/**
 * Configuration options for creating or updating a Trouble model.
 *
 * This interface defines all the properties that can be set when initializing
 * a trouble instance. Troubles represent issues, alerts, or conditions that
 * require attention in the KOS system.
 *
 * @template AdditionalData - Optional type parameter for domain-specific trouble data
 *
 * @example
 * ```typescript
 * const troubleOptions: TroubleOptions = {
 *   id: 'low-fluid-001',
 *   type: 'FLUID_LEVEL',
 *   reason: 'Fluid level below minimum threshold',
 *   rank: 7,
 *   role: 'operator',
 *   color: 'orange',
 *   resolvable: true,
 *   ifaces: ['fluid-monitor', 'alert-system'],
 *   tags: ['maintenance', 'fluid', 'warning'],
 *   createTime: new Date().toISOString()
 * };
 * ```
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Types
 */
export interface TroubleOptions<AdditionalData extends object = any> {
  /** Whether this trouble can be resolved through user action */
  resolvable?: boolean;
  /** Human-readable description of why the trouble occurred */
  reason?: string;
  /** ISO timestamp when the trouble was created */
  createTime?: string;
  /** List of interface identifiers this trouble affects */
  ifaces: string[];
  /** Unique identifier for the trouble instance */
  id: string;
  /** Priority rank from 1-10 (10 being most critical) */
  rank: number;
  /** User role required to view/resolve this trouble */
  role: string;
  /** Display color for UI representation (e.g., 'red', 'yellow', 'orange') */
  color: string;
  /** Client-specific data attached to the trouble */
  clientData: unknown;
  /** Classification type of the trouble (e.g., 'ERROR', 'WARNING', 'INFO') */
  type: string;
  /** Searchable tags for categorizing troubles */
  tags: string[];
  /** Additional information about the trouble state */
  info: unknown;
  /** Optional grouping identifier for related troubles */
  group?: string;
  /** Service path for the trouble instance */
  servicePath?: string;
  /** Raw JSON data for the trouble instance */
  rawJson?: TroubleResponse<any>;
  /** Index signature for additional domain-specific data */
  [key: keyof AdditionalData]: AdditionalData[key];
}

/**
 * Represents a trouble (issue, alert, or condition) in the KOS system.
 *
 * TroubleModel is the core interface for managing system issues, warnings, and
 * alerts throughout the KOS platform. It provides a unified way to track,
 * display, resolve, and defer various types of operational issues.
 *
 * ## Key Features
 * - **Priority ranking** - Troubles are ranked 1-10 for severity
 * - **Role-based visibility** - Troubles can be filtered by user role
 * - **Resolution support** - Resolvable troubles can be cleared through actions
 * - **Deferral capability** - Troubles can be temporarily deferred
 * - **Future integration** - Async resolution through futures
 * - **Type categorization** - Troubles grouped by type for filtering
 * - **Visual indicators** - Color coding for UI representation
 *
 * @template AdditionalData - Type parameter for domain-specific trouble data
 *
 * @interface
 * @example Basic Usage
 * ```typescript
 * function handleTrouble(trouble: TroubleModel) {
 *   if (trouble.rank >= 8) {
 *     console.error(`Critical trouble: ${trouble.reason}`);
 *   }
 *
 *   if (trouble.resolvable) {
 *     const futureResponse = await trouble.resolve();
 *   }
 * }
 * ```
 *
 * @useDeclaredType
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Trouble Management
 *
 * @see {@link TroubleAware} - Interface for models that can have troubles
 * @see {@link DeferAware} - Deferral capabilities
 * @see {@link ResolveAware} - Resolution capabilities
 */
export interface TroubleModel<AdditionalData extends object = any>
  extends IKosDataModel,
    DeferAware,
    FutureContainer {
  /** Unique identifier for the trouble instance */
  id: string;
  /** Whether this trouble can be resolved through user action */
  resolvable?: boolean;
  /** Human-readable description of why the trouble occurred */
  reason?: string;
  /** ISO timestamp when the trouble was created */
  createTime?: string;
  /** List of interface identifiers this trouble affects */
  ifaces: string[];
  /** Client-specific data attached to the trouble */
  clientData: unknown;
  /** Associated future for async resolution operations */
  future?: IFutureModel;
  /** Classification type of the trouble (e.g., 'ERROR', 'WARNING', 'INFO') */
  type: string;
  /** Searchable tags for categorizing troubles */
  tags: string[];
  /** Additional information about the trouble state */
  info: unknown;
  /** Original trouble ID before any transformations */
  rawId: string;
  /** Full response data object */
  rawJson?: TroubleResponse<any>;
  /** Resolves the trouble, returning a promise with the resolution response */
  resolve: () => Promise<FutureResponse | undefined>;
  /** Domain-specific additional data attached to the trouble */
  data: AdditionalData;
  /** Priority rank from 1-10 (10 being most critical) */
  rank: number;
  /** User role required to view/resolve this trouble */
  role: string;
  /** Display color for UI representation (e.g., 'red', 'yellow', 'orange') */
  color: string;
  /** Whether this trouble has been deferred */
  deferred: boolean;
  /** Optional grouping identifier for related troubles */
  group?: string;
}

/**
 * Domain-specific trouble data for handle-related issues.
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Domain Data
 */
export interface HandleTroubleData {
  /** Path to the affected handle component */
  path: string;
}

/**
 * Domain-specific trouble data for nozzle-related issues.
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Domain Data
 */
export interface NozzleTroubleData {
  /** Path to the affected nozzle component */
  nozzlePath: string;
}

/**
 * Domain-specific trouble data for container-related issues.
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Domain Data
 */
export interface ContainerTroubleData {
  /** Identifier of the affected container */
  containerId: string;
  /** List of ingredients involved in the trouble */
  ingredients: string[];
}

/**
 * Interface for objects that can be resolved asynchronously.
 *
 * Provides a standard resolution mechanism for troubles and other
 * resolvable conditions in the KOS system. Resolution typically
 * involves sending a command to clear the condition.
 *
 * @example
 * ```typescript
 * class ResolvableTrouble implements ResolveAware {
 *   async resolve(tracker?: string) {
 *     console.log(`Resolving with tracker: ${tracker}`);
 *     const response = await sendResolveCommand(this.id, tracker);
 *     return response;
 *   }
 * }
 * ```
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Capabilities
 */
export interface ResolveAware {
  /**
   * Resolves the condition asynchronously.
   *
   * @param tracker - Optional tracking identifier for the resolution operation
   * @returns Promise resolving to the future response, or undefined if resolution fails
   */
  resolve: (tracker?: string) => Promise<FutureResponse | undefined>;
}

/**
 * Interface for objects that support deferral of actions.
 *
 * Deferral allows temporary postponement of trouble handling or
 * other actions. Deferred items can be cleared to restore normal
 * processing. This is useful for managing low-priority issues
 * during critical operations.
 *
 * @example
 * ```typescript
 * class DeferrableTrouble implements DeferAware {
 *   shouldDefer = false;
 *   deferred = false;
 *
 *   defer() {
 *     this.deferred = true;
 *     console.log('Trouble deferred');
 *   }
 *
 *   clearDefer() {
 *     this.deferred = false;
 *     console.log('Deferral cleared');
 *   }
 * }
 *
 * // Usage
 * if (trouble.shouldDefer && !trouble.deferred) {
 *   trouble.defer();
 * }
 * ```
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Capabilities
 */
export interface DeferAware {
  /** Whether this item should be deferred based on current conditions */
  shouldDefer: boolean;
  /** Current deferral state */
  deferred: boolean;
  /** Defers the item, preventing normal processing */
  defer: VoidFunction;
  /** Clears the deferral, allowing normal processing to resume */
  clearDefer: VoidFunction;
}
/**
 * Interface for models that can track and expose trouble states.
 *
 * TroubleAware provides a standardized way for KOS models to expose
 * their trouble states, making it easy to monitor, display, and react
 * to issues throughout the system. Any model implementing this interface
 * can be monitored for troubles and integrated with trouble management UI.
 *
 * ## Key Concepts
 * - **Trouble aggregation** - Models can aggregate troubles from multiple sources
 * - **Status summary** - Provides a single status string for quick checks
 * - **Type grouping** - Troubles organized by type for filtering and display
 * - **Read-only access** - Troubles are exposed as readonly for safety
 *
 * @example
 * ```typescript
 * // Check if a model has troubles
 * function checkModelHealth(model: TroubleAware) {
 *   if (model.troubles.length > 0) {
 *     console.warn(`Model has ${model.troubles.length} troubles`);
 *     console.warn(`Status: ${model.troubleStatus}`);
 *
 *     // Check specific trouble types
 *     const errors = model.troublesByType['ERROR'] || [];
 *     const warnings = model.troublesByType['WARNING'] || [];
 *
 *     if (errors.length > 0) {
 *       handleCriticalErrors(errors);
 *     }
 *   }
 * }
 * ```
 *
 * @example
 * ```typescript
 * // React component using TroubleAware
 * const TroubleIndicator: React.FC<{ model: TroubleAware }> = ({ model }) => {
 *   const troubles = model.troubles;
 *   const highPriority = troubles.filter(t => t.rank >= 7);
 *
 *   if (troubles.length === 0) {
 *     return <StatusIcon color="green" />;
 *   }
 *
 *   return (
 *     <div className="trouble-indicator">
 *       <StatusIcon color={highPriority.length > 0 ? 'red' : 'yellow'} />
 *       <span>{model.troubleStatus}</span>
 *       <Badge count={troubles.length} />
 *     </div>
 *   );
 * };
 * ```
 *
 * @example
 * ```typescript
 * // Implementing TroubleAware
 * class MyModel implements TroubleAware {
 *   private _troubles: TroubleModel[] = [];
 *
 *   get troubles(): readonly TroubleModel[] {
 *     return this._troubles;
 *   }
 *
 *   get troubleStatus(): string {
 *     if (this._troubles.length === 0) return 'OK';
 *     const highest = this._troubles.reduce((max, t) =>
 *       t.rank > max.rank ? t : max
 *     );
 *     return highest.reason || 'Unknown issue';
 *   }
 *
 *   get troublesByType(): Record<string, TroubleModel[]> {
 *     return this._troubles.reduce((groups, trouble) => {
 *       const type = trouble.type;
 *       groups[type] = groups[type] || [];
 *       groups[type].push(trouble);
 *       return groups;
 *     }, {} as Record<string, TroubleModel[]>);
 *   }
 * }
 * ```
 *
 * @kosService core.trouble-aware
 * @group KOS Model
 * @category Interfaces
 *
 * @see {@link TroubleModel} - The trouble model interface
 * @see {@link isTroubleAware} - Type guard for checking TroubleAware
 * @see {@link useTroubleDecoration} - Hook for trouble-based styling
 */
export interface TroubleAware {
  /**
   * Array of troubles directly related to this model.
   * Troubles are typically sorted by rank (highest priority first).
   */
  readonly troubles: TroubleModel[];

  /**
   * Summary status string representing the highest priority trouble.
   * Returns a human-readable status or 'OK' if no troubles exist.
   */
  readonly troubleStatus: string;

  /**
   * Troubles organized by their type property.
   * Useful for filtering and categorized display of issues.
   *
   * @example
   * ```typescript
   * const errorTroubles = model.troublesByType['ERROR'] || [];
   * const warningTroubles = model.troublesByType['WARNING'] || [];
   * ```
   */
  readonly troublesByType: Record<string, TroubleModel[]>;
}
