import { Provider } from '@nestjs/common';

import { IMAGE_SERVICE_TOKEN, LOGGER_TOKEN, MEDIA_REPOSITORY_TOKEN, MEDIA_RESOLVER_TOKEN } from './TeamTokens';

export {
  TEAM_REPOSITORY_TOKEN,
  TEAM_MEMBERSHIP_REPOSITORY_TOKEN,
  DRIVER_REPOSITORY_TOKEN,
  IMAGE_SERVICE_TOKEN,
  LOGGER_TOKEN,
  MEDIA_REPOSITORY_TOKEN,
  MEDIA_RESOLVER_TOKEN,
} from './TeamTokens';

// Import core interfaces
import type { Logger } from '@core/shared/application/Logger';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';

// Import concrete implementations
import { InMemoryImageServiceAdapter } from '@adapters/media/ports/InMemoryImageServiceAdapter';
import { ConsoleLogger } from '@adapters/logging/ConsoleLogger';
import { InMemoryMediaRepository } from '@adapters/racing/persistence/media/InMemoryMediaRepository';
import { MediaResolverAdapter } from '@adapters/media/MediaResolverAdapter';

// Import presenters
import { AllTeamsPresenter } from './presenters/AllTeamsPresenter';

export const TeamProviders: Provider[] = [
  {
    provide: IMAGE_SERVICE_TOKEN,
    useFactory: (logger: Logger) => new InMemoryImageServiceAdapter(logger),
    inject: [LOGGER_TOKEN],
  },
  {
    provide: LOGGER_TOKEN,
    useClass: ConsoleLogger,
  },
  {
    provide: MEDIA_REPOSITORY_TOKEN,
    useFactory: (logger: Logger) => {
      const mediaRepo = new InMemoryMediaRepository(logger);
      
      // Override getTeamLogo to provide fallback URLs
      const originalGetTeamLogo = mediaRepo.getTeamLogo.bind(mediaRepo);
      mediaRepo.getTeamLogo = async (teamId: string): Promise<string | null> => {
        const logo = await originalGetTeamLogo(teamId);
        if (logo) return logo;
        
        // Fallback: generate deterministic team logo URL
        // Use API port (3001) for media generation
        const baseUrl = process.env.NODE_ENV === 'development' ? 'http://localhost:3001' : 'https://api.gridpilot.io';
        return `${baseUrl}/media/teams/${teamId}/logo`;
      };
      
      return mediaRepo;
    },
    inject: [LOGGER_TOKEN],
  },
  {
    provide: MEDIA_RESOLVER_TOKEN,
    useFactory: () => new MediaResolverAdapter({}),
  },
  {
    provide: AllTeamsPresenter,
    useFactory: (mediaResolver: MediaResolverPort) => {
      const presenter = new AllTeamsPresenter();
      presenter.setMediaResolver(mediaResolver);
      return presenter;
    },
    inject: [MEDIA_RESOLVER_TOKEN],
  },
];