import type * as plugins from '../plugins.js';

// Re-export S3 change event from smartbucket
export type { IS3ChangeEvent } from '@push.rocks/smartbucket';

/**
 * MongoDB change event - wraps smartdata watcher output
 */
export interface IMongoChangeEvent {
  type: 'insert' | 'update' | 'delete' | 'replace' | 'drop' | 'invalidate';
  database: string;
  collection: string;
  documentId?: string;
  document?: Record<string, unknown>;
  updateDescription?: {
    updatedFields?: Record<string, unknown>;
    removedFields?: string[];
  };
  timestamp: string;
}

/**
 * Combined activity event for the activity stream
 */
export interface IActivityEvent {
  id: string;
  source: 'mongodb' | 's3';
  event: IMongoChangeEvent | import('@push.rocks/smartbucket').IS3ChangeEvent;
  timestamp: string;
}

// ===========================================
// TypedRequest interfaces for streaming subscriptions
// ===========================================

/**
 * Subscribe to MongoDB collection changes
 */
export interface IReq_SubscribeMongo extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_SubscribeMongo
> {
  method: 'subscribeMongo';
  request: {
    database: string;
    collection: string;
  };
  response: {
    success: boolean;
    subscriptionId: string;
  };
}

/**
 * Unsubscribe from MongoDB collection changes
 */
export interface IReq_UnsubscribeMongo extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_UnsubscribeMongo
> {
  method: 'unsubscribeMongo';
  request: {
    database: string;
    collection: string;
  };
  response: {
    success: boolean;
  };
}

/**
 * Subscribe to S3 bucket/prefix changes
 */
export interface IReq_SubscribeS3 extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_SubscribeS3
> {
  method: 'subscribeS3';
  request: {
    bucket: string;
    prefix?: string;
  };
  response: {
    success: boolean;
    subscriptionId: string;
  };
}

/**
 * Unsubscribe from S3 bucket/prefix changes
 */
export interface IReq_UnsubscribeS3 extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_UnsubscribeS3
> {
  method: 'unsubscribeS3';
  request: {
    bucket: string;
    prefix?: string;
  };
  response: {
    success: boolean;
  };
}

/**
 * Subscribe to activity stream (all changes from MongoDB and S3)
 */
export interface IReq_SubscribeActivity extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_SubscribeActivity
> {
  method: 'subscribeActivity';
  request: {};
  response: {
    success: boolean;
    subscriptionId: string;
  };
}

/**
 * Unsubscribe from activity stream
 */
export interface IReq_UnsubscribeActivity extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_UnsubscribeActivity
> {
  method: 'unsubscribeActivity';
  request: {};
  response: {
    success: boolean;
  };
}

/**
 * Get recent activity events (for initial load or reconnection)
 */
export interface IReq_GetRecentActivity extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_GetRecentActivity
> {
  method: 'getRecentActivity';
  request: {
    limit?: number; // Default: 100
  };
  response: {
    events: IActivityEvent[];
  };
}

// ===========================================
// Server-to-client push event interfaces
// ===========================================

/**
 * Server pushes MongoDB change to client
 */
export interface IReq_PushMongoChange extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_PushMongoChange
> {
  method: 'pushMongoChange';
  request: {
    event: IMongoChangeEvent;
  };
  response: {
    received: boolean;
  };
}

/**
 * Server pushes S3 change to client
 */
export interface IReq_PushS3Change extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_PushS3Change
> {
  method: 'pushS3Change';
  request: {
    event: import('@push.rocks/smartbucket').IS3ChangeEvent;
  };
  response: {
    received: boolean;
  };
}

/**
 * Server pushes activity event to client
 */
export interface IReq_PushActivityEvent extends plugins.typedrequestInterfaces.implementsTR<
  plugins.typedrequestInterfaces.ITypedRequest,
  IReq_PushActivityEvent
> {
  method: 'pushActivityEvent';
  request: {
    event: IActivityEvent;
  };
  response: {
    received: boolean;
  };
}

/**
 * Connection tag for tracking subscriptions
 */
export interface ISubscriptionTag extends plugins.typedrequestInterfaces.ITag {
  name: 'subscription';
  payload: {
    type: 'mongo' | 's3' | 'activity';
    key: string; // e.g., "db/collection" or "bucket/prefix" or "activity"
  };
}
