/**
 * Port: MediaResolverPort
 * 
 * Interface for resolving MediaReference objects to actual URLs.
 * Part of the clean architecture ports layer.
 * 
 * Implementations:
 * - InMemoryMediaResolverAdapter (for tests/stubs)
 * - HttpMediaResolverAdapter (for production HTTP resolution)
 * - FileSystemMediaResolverAdapter (for local file resolution)
 */

import { MediaReference } from '@core/domain/media/MediaReference';

/**
 * MediaResolverPort interface
 * 
 * Resolves a MediaReference to a concrete path string or null if no media exists.
 * Returns path-only URLs (e.g., /media/teams/123/logo) without baseUrl.
 * 
 * @param ref - The media reference to resolve
 * @returns Promise resolving to a path string or null
 * 
 * @example
 * ```typescript
 * const resolver: MediaResolverPort = new MediaResolverAdapter();
 * const ref = MediaReference.createSystemDefault('avatar');
 * const path = await resolver.resolve(ref);
 * // Returns: '/media/default/male-default-avatar.png'
 * ```
 */
export interface MediaResolverPort {
  /**
   * Resolve a media reference to a path-only URL
   * 
   * @param ref - The media reference to resolve
   * @returns Promise resolving to path string or null (for 'none' type or resolution failures)
   * 
   * @throws Should not throw for valid inputs - returns null instead
   * @throws May throw for invalid inputs (null ref)
   */
  resolve(ref: MediaReference): Promise<string | null>;
}

/**
 * Type guard to check if an object implements MediaResolverPort
 */
export function isMediaResolverPort(obj: unknown): obj is MediaResolverPort {
  const typedObj = obj as MediaResolverPort;
  return (
    obj !== null &&
    typeof obj === 'object' &&
    typeof typedObj.resolve === 'function'
  );
}

/**
 * Default resolution strategies for different reference types
 * Returns path-only URLs
 */
export const ResolutionStrategies = {
  /**
   * Resolve system-default references
   * Format: /media/default/{variant}
   */
  systemDefault: (ref: MediaReference): string | null => {
    if (ref.type !== 'system-default') return null;
    
    let filename: string;
    if (ref.variant === 'avatar' && ref.avatarVariant) {
      filename = `${ref.avatarVariant}-default-avatar.png`;
    } else if (ref.variant === 'avatar') {
      filename = `neutral-default-avatar.png`;
    } else {
      filename = `${ref.variant}.png`;
    }
    
    return `/media/default/${filename}`;
  },

  /**
   * Resolve generated references
   * Format: /media/teams/{id}/logo, /media/leagues/{id}/logo, /media/avatar/{id}
   */
  generated: (ref: MediaReference): string | null => {
    if (ref.type !== 'generated') return null;
    
    if (!ref.generationRequestId) {
      return null;
    }
    
    const firstHyphenIndex = ref.generationRequestId.indexOf('-');
    if (firstHyphenIndex === -1) {
      return null;
    }

    const type = ref.generationRequestId.substring(0, firstHyphenIndex);
    const id = ref.generationRequestId.substring(firstHyphenIndex + 1);

    if (type === 'team') {
      return `/media/teams/${id}/logo`;
    } else if (type === 'league') {
      return `/media/leagues/${id}/logo`;
    } else if (type === 'driver') {
      return `/media/avatar/${id}`;
    }
    
    return `/media/generated/${type}/${id}`;
  },

  /**
   * Resolve uploaded references
   * Format: /media/uploaded/{mediaId}
   */
  uploaded: (ref: MediaReference): string | null => {
    if (ref.type !== 'uploaded') return null;
    if (!ref.mediaId) return null;
    return `/media/uploaded/${ref.mediaId}`;
  },

  /**
   * Resolve none references
   * Returns: null
   */
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  none: (_ref: MediaReference): string | null => {
    return null;
  },
} as const;

/**
 * Helper function to resolve using default strategies
 */
export function resolveWithDefaults(ref: MediaReference): string | null {
  switch (ref.type) {
    case 'system-default':
      return ResolutionStrategies.systemDefault(ref);
    case 'generated':
      return ResolutionStrategies.generated(ref);
    case 'uploaded':
      return ResolutionStrategies.uploaded(ref);
    case 'none':
      return ResolutionStrategies.none(ref);
    default:
      // Exhaustive check - TypeScript will error if we miss a case
      return null;
  }
}