interface FileManageErrorInfo {
  message?: string;
  code?: FileManagerErrorCode;
  status?: number;
  raw?: any;
  stack?: string;
}

/**
 * Error codes for FileManager API operations.
 */
type FileManagerErrorCode =
  // --- Files ---
  | 'FileNotFound'
  | 'FileAlreadyExists'
  | 'FileInvalidName'
  | 'FileAccessDenied'
  | 'FileReadError'
  | 'FileWriteError'
  | 'FileTooLarge'
  | 'FileTypeNotAllowed'
  | 'FileCorrupted'
  | 'FileChecksumMismatch'
  | 'FileStorageQuotaExceeded'
  | 'FileLocked'
  | 'FileVersionConflict'

  // --- Folders / directories ---
  | 'FolderNotFound'
  | 'FolderAlreadyExists'
  | 'FolderInvalidName'
  | 'FolderAccessDenied'
  | 'FolderReadError'
  | 'FolderWriteError'
  | 'FolderQuotaExceeded'
  | 'FolderNotEmpty'
  | 'FolderBackendError'
  | 'FolderTimeout'

  // --- Operational restrictions ---
  | 'RenameNotAllowed'
  | 'MoveNotAllowed'
  | 'CopyNotAllowed'
  | 'DeleteNotAllowed'
  | 'MoveIntoSelf'
  | 'MoveIntoDescendant'
  | 'CopyIntoSelf'
  | 'UnsupportedOperation'
  | 'ConfigError'

  // --- File upload ---
  | 'FileUploadQuotaExceeded'
  | 'FileUploadNetworkError'
  | 'FileUploadTimeout'
  | 'FileUploadBackendError'

  // --- URL upload ---
  | 'UploadUrlInvalid'
  | 'UploadUrlNotReachable'
  | 'UploadUrlContentTypeNotAllowed'
  | 'UploadUrlDownloadFailed'
  | 'FileLookupFailed'
  | 'FileProxyFailed'
  | 'FileProxyNotConfigured'

  // --- File download ---
  | 'FileDownloadNetworkError'
  | 'FileDownloadTimeout'
  | 'FileDownloadBackendError'

  // --- Batch operations ---
  | 'BatchPartialFailure'
  | 'BatchAllFailed'
  | 'BatchConflict'
  | 'BatchValidationFailed'
  | 'BatchItemLimitExceeded'

  // --- Validation / data ---
  | 'ValidationError'
  | 'PayloadTooLarge'
  | 'UnsupportedMediaType'

  // --- Network / server / infrastructure ---
  | 'NetworkError'
  | 'BackendError'
  | 'Timeout'
  | 'AuthenticationFailed'
  | 'AuthorizationFailed'
  | 'RateLimitExceeded'
  | 'ServiceUnavailable'

  // --- AI / integrations ---
  | 'AIResponseInvalid'
  | 'AIImageGenerationFailed'
  | 'AIImageGenerationLimitExceeded'
  | 'IntegrationError'
  | 'ThirdPartyError'

  // --- General / fallback ---
  | 'UnknownError';

/**
 * Error interface for FileManager API.
 * Implemented by FileManagerApiError class which is also exported.
 *
 * @example
 * ```typescript
 * // Using the class
 * throw new FileManagerApiError(
 *   'File not found',
 *   'FileNotFound',
 *   404
 * );
 *
 * // Or creating a custom class
 * class MyFileManagerError extends Error implements IFileManagerApiError {
 *   constructor(
 *     message: string,
 *     public code: FileManagerErrorCode,
 *     public status?: number,
 *     public details?: unknown
 *   ) {
 *     super(message);
 *     this.name = 'MyFileManagerError';
 *   }
 * }
 * ```
 */
interface IFileManagerApiError extends Error {
  code: FileManagerErrorCode;
  status?: number;
  details?: unknown;
}

/**
 * Parameters for file query operations.
 */
interface FilesQueryParams {
  folderId?: string;
  search?: string;
  page?: number;
  limit?: number;
  sortBy?: 'name' | 'size' | 'date' | 'type';
  sortOrder?: 'asc' | 'desc';
  itemType?: 'file' | 'folder' | 'all';
  /** Человекочитаемое имя папки для UI (не отправляется на API). */
  folderName?: string;
}

/**
 * Context payload for operations involving items (files/folders).
 */
interface ItemContextPayload {
  itemIds?: string[];
  itemNames?: string[];
  folderId?: string | null;
  folderName?: string | null;
}

/**
 * Placement options for notification display.
 */
type NotifyPlacement = 'top' | 'topLeft' | 'topRight' | 'bottom' | 'bottomLeft' | 'bottomRight';

type Notify = {
  type: 'success' | 'info' | 'error' | 'warning';
  message: HTMLElement | string;
  description?: HTMLElement | string;
  btn?: HTMLElement | string;
  onClose?: () => void;
  duration?: number | null;
  icon?: HTMLElement | string;
  placement?: NotifyPlacement;
  style?: any;
  className?: string;
  onClick?: () => void;
  closeIcon?: HTMLElement | string;
  props?: any;
  role?: 'alert' | 'status';
};

declare namespace Notify {
  /**
   * Payload for successful batch operations.
   */
  export interface OperationSuccessPayload extends ItemContextPayload {
    successCount: number;
    totalCount: number;
    eventSource?: UploadEventSource;
  }

  /**
   * Details of an error for a single item in a batch operation.
   */
  export interface OperationErrorDetail {
    itemId?: string;
    itemName?: string;
    error: FileManageErrorInfo;
  }

  /**
   * Payload for batch operation errors.
   * Extends ItemContextPayload with error-specific fields.
   */
  export interface OperationErrorPayload extends ItemContextPayload {
    failCount: number;
    totalCount: number;
    errors?: OperationErrorDetail[];
    /**
     * Flag indicating if this is a move-to-trash operation (true) or permanent delete (false).
     * Used to differentiate between soft delete (trash) and hard delete operations.
     */
    isTrashMove?: boolean;
    eventSource?: UploadEventSource;
  }

  /**
   * Details of a single item in batch operation results.
   * Used in the `detailed` array for batch operations (deleteItems, moveItems, copyItems, uploadFiles).
   *
   * @template T - Type of successful operation result data
   */
  export interface BatchOperationDetail<T = unknown> {
    /** Correlation identifier for the request item (preferred) */
    requestId?: string;
    /** Item identifier (for backward compatibility) */
    id?: string;
    /** Success flag for the operation */
    success: boolean;
    /** Successful operation result data */
    data?: T;
    /** Error for failed operation */
    error?: FileManageErrorInfo;
  }

  /**
   * Result of a batch operation with support for detailed results.
   * Unified type for all batch operations in the file manager.
   *
   * @template T - Type of successful operation result data
   */
  export interface BatchOperationResult<T = unknown> {
    /** Overall success flag (true if all items succeeded) */
    success: boolean;
    /** Overall operation error (if the entire operation failed) */
    error?: string | unknown;
    /** Detailed results for each item */
    detailed?: BatchOperationDetail<T>[];
  }

  /**
   * Summary of batch operation results for notifications.
   * Used for aggregated error and success notifications.
   */
  export interface BatchOperationSummary {
    /** Number of successfully processed items */
    successCount: number;
    /** Number of items with errors */
    failCount: number;
    /** Total number of items */
    totalCount: number;
    /** Error details for each item */
    errors: OperationErrorDetail[];
  }

  /**
   * Payload for operations involving a single item (file or folder).
   */
  export interface SingleItemPayload {
    itemId?: string;
    itemName?: string;
    folderId?: string | null;
    folderName?: string | null;
  }

  /**
   * Payload for rename operation errors.
   */
  export interface RenameErrorPayload extends SingleItemPayload {
    error: FileManageErrorInfo;
  }

  /**
   * Source of the upload event: 'upload' for file picker/drag-drop, 'uploadByUrl' for URL upload.
   */
  export type UploadEventSource = 'upload' | 'uploadByUrl' | 'pixie' | 'iconStock' | 'imageStock' | 'gif';

  /**
   * Payload for file upload operations.
   */
  export interface FileUploadPayload extends SingleItemPayload {
    uploadId?: string;
    eventSource?: UploadEventSource;
  }

  /**
   * Payload for file upload errors.
   */
  export interface FileUploadErrorPayload extends FileUploadPayload {
    error?: FileManageErrorInfo;
  }

  /**
   * Payload for unsupported file type errors.
   */
  export interface UnsupportedFileTypePayload extends FileUploadErrorPayload {
    fileType: string;
  }

  /**
   * Payload for folder operation errors and successes.
   */
  export interface FolderOperationPayload extends ItemContextPayload {
    folderId?: string | null;
    folderName?: string;
    reason?: string;
    is_force_create?: boolean;
  }

  /**
   * Payload for file URL validation errors.
   */
  export interface FileUrlValidationErrorPayload {
    url?: string | null;
    error: FileManageErrorInfo;
  }

  /**
   * Payload for image file operations.
   */
  export interface ImageFilePayload extends SingleItemPayload {
    thumbnail?: string | null;
  }

  /**
   * Payload for URL upload operations.
   */
  export interface UrlUploadPayload {
    url?: string | null;
    folderId?: string | null;
    folderName?: string | null;
    eventSource?: UploadEventSource;
  }

  /**
   * Payload for URL upload errors.
   */
  export interface UrlUploadErrorPayload extends UrlUploadPayload {
    error: FileManageErrorInfo;
  }

  /**
   * Payload for file fetch errors.
   */
  export interface FetchFilesErrorPayload {
    params?: FilesQueryParams;
    /** Отображаемое имя папки списка (после resolve getItem / path / кэша). */
    folderName?: string | null;
  }

  /**
   * Base payload for AI image generation operations.
   */
  interface AIImageGenerationBasePayload {
    request: string;
    taskId?: string | null;
  }

  /**
   * Payload for AI image generation started event.
   */
  export interface AIImageGenerationStartedPayload extends AIImageGenerationBasePayload {
    response?: unknown;
  }

  /**
   * Payload for successful AI image generation.
   */
  export interface AIImageGenerationSuccessPayload extends AIImageGenerationBasePayload {
    images: string[];
  }

  /**
   * Payload for failed AI image generation.
   */
  export interface AIImageGenerationFailedPayload extends AIImageGenerationBasePayload {
    response?: unknown;
    error?: FileManageErrorInfo;
  }

  /**
   * Base type for error notification events.
   * Includes innerException field for error details.
   *
   * @template TId - Notification event ID type
   * @template TData - Payload data type
   */
  export type ErrorEventBase<TId extends string, TData> = {
    id: TId;
    data?: TData;
    innerException?: unknown;
    message: string;
    placement?: NotifyPlacement;
    description?: string;
    /**
     * Visibility flag for the notification.
     * If true, notification will be shown; if false, it will be silent.
     * Derived from the `silent` parameter (visibility = !silent).
     * Can be modified by event interceptors.
     */
    visibility?: boolean;
    /**
     * Level of the operation: 'item' for single item operations, 'batch' for batch operations.
     */
    level?: 'item' | 'batch';
    /**
     * Если true — применять TTL-дедупликацию одинаковых уведомлений (после interceptors).
     * Для upload/мутаций обычно не задаётся или false.
     */
    notificationDedupe?: boolean;
  };

  /**
   * Base type for success, warning, and info notification events.
   * Does not include innerException field.
   *
   * @template TId - Notification event ID type
   * @template TData - Payload data type
   */
  export type NotificationEventBase<TId extends string, TData> = {
    id: TId;
    data?: TData;
    message: string;
    placement?: NotifyPlacement;
    description?: string;
    /**
     * Visibility flag for the notification.
     * If true, notification will be shown; if false, it will be silent.
     * Derived from the `silent` parameter (visibility = !silent).
     * Can be modified by event interceptors.
     */
    visibility?: boolean;
    /**
     * Level of the operation: 'item' for single item operations, 'batch' for batch operations.
     */
    level?: 'item' | 'batch';
  };

  /**
   * Map of error notification IDs to their payload types for single item operations.
   * All item operation errors extend OperationErrorPayload with failCount: 1 and totalCount: 1.
   */
  export interface ItemErrorMap {
    FILE_DELETE_ERROR: OperationErrorPayload;
    FILE_MOVE_ERROR: OperationErrorPayload;
    FILE_COPY_ERROR: OperationErrorPayload;
  }

  /**
   * Map of error notification IDs to their payload types for batch operations.
   * All batch operation errors extend OperationErrorPayload.
   */
  export interface BatchErrorMap {
    FILES_DELETE_ERROR: OperationErrorPayload;
    FOLDER_DELETE_ERROR: OperationErrorPayload;
    FILES_UPLOAD_BATCH_FAILED: OperationErrorPayload;
    FILES_MOVE_ERROR: OperationErrorPayload;
    FILES_COPY_ERROR: OperationErrorPayload;
  }

  /**
   * Map of success notification IDs to their payload types for single item operations.
   * All item operation successes extend OperationSuccessPayload with successCount: 1 and totalCount: 1.
   */
  export interface ItemSuccessMap {
    FILE_DELETE_SUCCESS: OperationSuccessPayload;
    FILE_MOVE_SUCCESS: OperationSuccessPayload;
    FILE_COPY_SUCCESS: OperationSuccessPayload;
  }

  /**
   * Map of success notification IDs to their payload types for batch operations.
   * All batch operation successes extend OperationSuccessPayload.
   */
  export interface BatchSuccessMap {
    FILES_DELETE_SUCCESS: OperationSuccessPayload;
    FILES_MOVE_SUCCESS: OperationSuccessPayload;
    FILES_COPY_SUCCESS: OperationSuccessPayload;
    FOLDER_DELETE_SUCCESS: OperationSuccessPayload;
    FILES_UPLOAD_BATCH_SUCCESS: OperationSuccessPayload;
  }

  /**
   * Map of all error notification IDs to their payload types.
   * Extends ItemErrorMap for single item operations and BatchErrorMap for batch operations.
   */
  export interface ErrorMap extends ItemErrorMap, BatchErrorMap {
    FILE_DOWNLOAD_FAILED: ImageFilePayload;
    IMAGE_DOWNLOAD_FAILED: ImageFilePayload;
    IMAGE_SAVE_FAILED: ImageFilePayload;
    IMAGE_SAVE_COPY_FAILED: ImageFilePayload;
    EDITOR_INIT_FAILED: never;
    EDITOR_FIND_FILE_BY_URL_FAILED: UrlUploadErrorPayload;
    EDITOR_PROXY_FILE_FAILED: UrlUploadErrorPayload;

    AI_RESPONSE_INVALID: unknown;
    AI_IMAGE_GENERATION_FAILED: AIImageGenerationFailedPayload;
    AI_IMAGE_GENERATION_LIMIT_EXCEEDED: never;

    FILES_FETCH_FAILED: FetchFilesErrorPayload;

    FILE_RENAME_DISABLED_BY_CONFIG: SingleItemPayload;
    FILE_RENAME_FAILED: RenameErrorPayload;

    FOLDER_RENAME_DISABLED_BY_CONFIG: SingleItemPayload;
    FOLDER_RENAME_FAILED: RenameErrorPayload;

    ITEM_RENAME_FAILED: RenameErrorPayload;

    FILE_UPLOAD_ITEM_FAILED: FileUploadErrorPayload;

    FILES_UPLOAD_URL_VALIDATION_FAILED: UrlUploadPayload;

    FILES_UPLOAD_URL_NOT_SUPPORTED: UrlUploadPayload;
    FILES_UPLOAD_BY_URL_FAILED: UrlUploadErrorPayload;

    FILES_UPLOAD_PROVIDER_NOT_CONFIGURED: never;

    FILES_MOVE_DIRECTORY_NOT_SELECTED: never;

    FILES_COPY_DIRECTORY_NOT_SELECTED: never;

    FOLDERS_FETCH_FAILED: FolderOperationPayload;
    FOLDER_ALREADY_EXISTS: FolderOperationPayload;
    FOLDER_ALREADY_EXISTS_COPY: FolderOperationPayload & { targetFolderId?: string };
    FOLDER_ALREADY_EXISTS_MOVE: FolderOperationPayload & { targetFolderId?: string };
    FOLDER_CREATE_PROVIDER_NOT_CONFIGURED: FolderOperationPayload;
    FOLDER_CREATE_FAILED: FolderOperationPayload;
    FOLDER_CHILDREN_COUNT_FAILED: FolderOperationPayload;
    FOLDER_CHILDREN_FETCH_FAILED: FolderOperationPayload;
    FILE_URL_VALIDATION_FAILED: FileUrlValidationErrorPayload;

    TRASH_CLEAR_FAILED: OperationErrorPayload;
    TRASH_CLEAR_ERROR: never;
  }

  /**
   * Union type of all error events.
   */
  export type Error = {
    [K in keyof ErrorMap]: ErrorEventBase<K, ErrorMap[K]>;
  }[keyof ErrorMap];

  /**
   * Error notification event type.
   */
  export type ErrorEvent = { type: 'error' } & Error;

  /**
   * Map of all success notification IDs to their payload types.
   * Extends ItemSuccessMap for single item operations and BatchSuccessMap for batch operations.
   */
  export interface SuccessMap extends ItemSuccessMap, BatchSuccessMap {
    AI_IMAGE_GENERATION_STARTED: AIImageGenerationStartedPayload;
    AI_IMAGE_GENERERATION_SUCCESS: AIImageGenerationSuccessPayload;

    // EDITOR_IMAGE_DOWNLOAD_SUCCESS: ImageFilePayload;
    IMAGE_UPDATE_SUCCESS: ImageFilePayload;
    IMAGE_SAVE_COPY_SUCCESS: ImageFilePayload;

    FILE_RENAME_SUCCESS: SingleItemPayload;
    FOLDER_RENAME_SUCCESS: SingleItemPayload;
    FOLDER_CREATE_SUCCESS: FolderOperationPayload;

    FILE_UPLOAD_ITEM_SUCCESS: FileUploadPayload;

    TRASH_CLEARED_SUCCESS: never;

    FOLDER_NOT_FOUND_NAVIGATE: never;
  }

  /**
   * Union type of all success events.
   */
  export type Success = {
    [K in keyof SuccessMap]: NotificationEventBase<K, SuccessMap[K]>;
  }[keyof SuccessMap];

  /**
   * Success notification event type.
   */
  export type SuccessEvent = { type: 'success' } & Success;

  /**
   * Map of warning notification IDs to their payload types.
   */
  export interface WarningMap {
    FILES_UPLOAD_UNSUPPORTED_TYPE: UnsupportedFileTypePayload;
    FOLDER_OPERATION_VALIDATION_FAILED: FolderOperationPayload;

    TRASH_CLEARED_PARTIAL: OperationErrorPayload;
  }

  /**
   * Union type of all warning events.
   */
  export type Warning = {
    [K in keyof WarningMap]: NotificationEventBase<K, WarningMap[K]>;
  }[keyof WarningMap];

  /**
   * Warning notification event type.
   */
  export type WarningEvent = { type: 'warning' } & Warning;

  /**
   * Map of info notification IDs to their payload types.
   */
  export interface InfoMap {}

  /**
   * Union type of all info events.
   */
  export type Info = {
    [K in keyof InfoMap]: NotificationEventBase<K, InfoMap[K]>;
  }[keyof InfoMap];

  /**
   * Info notification event type.
   */
  export type InfoEvent = { type: 'info' } & Info;
}

/**
 * Union type of all notification events (error, success, warning, info).
 */
type NotifyEvent = Notify.SuccessEvent | Notify.ErrorEvent | Notify.WarningEvent | Notify.InfoEvent;

export { Notify };
export type { FileManageErrorInfo, FileManagerErrorCode, FilesQueryParams, IFileManagerApiError, ItemContextPayload, NotifyEvent, NotifyPlacement };
