/**
 * @module BaseRequestHandler
 * @description Base interfaces for request handling in the A2A protocol server
 * 
 * This module provides the base interfaces for request handling in the A2A protocol
 * server, including middleware support, message handling, task management, and
 * error handling.
 */

import { Router, Request, Response, NextFunction } from 'express';
import { MessagePart, Task, AgentCard, A2AError } from '@dexwox-labs/a2a-core';
import { z } from 'zod';

/**
 * Express middleware function type
 * 
 * This interface defines the signature for middleware functions used in the
 * A2A protocol server. Middleware functions process HTTP requests and can
 * either respond to the request or pass control to the next middleware.
 * 
 * @example
 * ```typescript
 * const loggingMiddleware: Middleware = async (req, res, next) => {
 *   console.log(`${req.method} ${req.path}`);
 *   await next();
 * };
 * ```
 */
export interface Middleware {
  (req: Request, res: Response, next: NextFunction): Promise<void>;
}

/**
 * Base interface for request handlers in the A2A protocol server
 * 
 * This interface defines the core functionality required for all request handlers
 * in the A2A protocol server, including middleware support, message handling,
 * task management, and error handling.
 * 
 * @example
 * ```typescript
 * class MyRequestHandler implements BaseRequestHandler {
 *   readonly router = Router();
 *   
 *   constructor() {
 *     this.router.post('/send-message', async (req, res) => {
 *       const { parts, agentId } = req.body;
 *       const taskId = await this.handleSendMessage(parts, agentId);
 *       res.json({ taskId });
 *     });
 *   }
 *   
 *   // Implement all required methods...
 * }
 * ```
 */
export interface BaseRequestHandler {
  /** Express router for handling HTTP requests */
  readonly router: Router;
  
  /**
   * Adds middleware to the request handler
   * 
   * @param middleware - Middleware function to add
   */
  use(middleware: Middleware): void;
  
  /**
   * Creates middleware for validating request body against a schema
   * 
   * @param schema - Zod schema to validate against
   * @returns Middleware function that validates requests
   */
  validateRequest(schema: z.ZodSchema): Middleware;
  
  /**
   * Creates middleware for handling errors
   * 
   * @returns Middleware function that catches and processes errors
   */
  handleErrors(): Middleware;
  
  /**
   * Creates middleware for formatting responses
   * 
   * @returns Middleware function that formats responses
   */
  formatResponse(): Middleware;

  /**
   * Handles sending a message to an agent
   * 
   * @param parts - Message parts to send
   * @param agentId - ID of the target agent
   * @returns Promise resolving to the created task ID
   */
  handleSendMessage(parts: MessagePart[], agentId: string): Promise<string>;
  
  /**
   * Handles streaming a message to an agent
   * 
   * @param parts - Message parts to send
   * @param agentId - ID of the target agent
   * @returns AsyncGenerator yielding message parts as they are processed
   */
  handleStreamMessage(parts: MessagePart[], agentId: string): AsyncGenerator<MessagePart, void, unknown>;

  /**
   * Gets the status of a task
   * 
   * @param taskId - ID of the task
   * @returns Promise resolving to the task object
   */
  handleGetTaskStatus(taskId: string): Promise<Task>;
  
  /**
   * Cancels a running task
   * 
   * @param taskId - ID of the task to cancel
   * @returns Promise resolving when the task is canceled
   */
  handleCancelTask(taskId: string): Promise<void>;
  
  /**
   * Resubscribes to a task's message stream
   * 
   * @param taskId - ID of the task
   * @returns AsyncGenerator yielding message parts for the task
   */
  handleTaskResubscription(taskId: string): AsyncGenerator<MessagePart, void, unknown>;

  /**
   * Normalizes errors to A2AError format
   * 
   * @param err - Error to normalize
   * @returns Normalized A2AError
   */
  normalizeError(err: unknown): A2AError;
}
