/**
 * MediaResolverAdapter (Composite)
 * 
 * Composite adapter that delegates resolution to type-specific adapters.
 * This is the main entry point for media resolution.
 */

import { MediaReference } from '@core/domain/media/MediaReference';
import { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import { DefaultMediaResolverAdapter } from './resolvers/DefaultMediaResolverAdapter';
import { GeneratedMediaResolverAdapter } from './resolvers/GeneratedMediaResolverAdapter';
import { UploadedMediaResolverAdapter } from './resolvers/UploadedMediaResolverAdapter';

/**
 * Configuration for the composite MediaResolverAdapter
 */
export interface MediaResolverAdapterConfig {
  /**
   * Base path for default assets (defaults to '/media/default')
   */
  defaultPath?: string;
  
  /**
   * Base path for generated assets (defaults to '/media/generated')
   */
  generatedPath?: string;
  
  /**
   * Base path for uploaded assets (defaults to '/media/uploaded')
   */
  uploadedPath?: string;
}

/**
 * MediaResolverAdapter
 * 
 * Composite adapter that delegates to type-specific resolvers.
 * Implements the MediaResolverPort interface.
 * 
 * Returns path-only URLs (e.g., /media/teams/123/logo) without baseUrl.
 * 
 * Usage:
 * ```typescript
 * const resolver = new MediaResolverAdapter({
 *   defaultPath: '/media/default',
 *   generatedPath: '/media/generated',
 *   uploadedPath: '/media/uploaded'
 * });
 * 
 * const path = await resolver.resolve(mediaReference);
 * ```
 */
export class MediaResolverAdapter implements MediaResolverPort {
  private readonly defaultResolver: DefaultMediaResolverAdapter;
  private readonly generatedResolver: GeneratedMediaResolverAdapter;
  private readonly uploadedResolver: UploadedMediaResolverAdapter;

  constructor(config: MediaResolverAdapterConfig = {}) {
    // Initialize type-specific resolvers
    this.defaultResolver = new DefaultMediaResolverAdapter({
      basePath: config.defaultPath
    });
    
    this.generatedResolver = new GeneratedMediaResolverAdapter({
      basePath: config.generatedPath
    });
    
    this.uploadedResolver = new UploadedMediaResolverAdapter({
      basePath: config.uploadedPath
    });
  }

  /**
   * Resolve a media reference to a path-only URL
   * 
   * Delegates to the appropriate type-specific resolver based on the reference type.
   * Returns paths like /media/... (no baseUrl).
   */
  async resolve(ref: MediaReference): Promise<string | null> {
    if (!ref) {
      return null;
    }

    // Delegate to the appropriate resolver based on type
    switch (ref.type) {
      case 'system-default':
        return this.defaultResolver.resolve(ref);
      
      case 'generated':
        return this.generatedResolver.resolve(ref);
      
      case 'uploaded':
        return this.uploadedResolver.resolve(ref);
      
      case 'none':
        return null;
      
      default:
        // Unknown type
        return null;
    }
  }
}

/**
 * Factory function for creating MediaResolverAdapter instances
 */
export function createMediaResolver(
  config: MediaResolverAdapterConfig = {}
): MediaResolverAdapter {
  return new MediaResolverAdapter(config);
}

/**
 * Default configuration for development/testing
 */
export const DefaultResolvers = {
  /**
   * Creates a resolver for local development
   */
  local: () => createMediaResolver({}),

  /**
   * Creates a resolver for production
   */
  production: () => createMediaResolver({})
};