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

// Import core interfaces
import { AvatarGenerationPort } from '@core/media/application/ports/AvatarGenerationPort';
import { FaceValidationPort } from '@core/media/application/ports/FaceValidationPort';
import { MediaStoragePort } from '@core/media/application/ports/MediaStoragePort';
import { AvatarGenerationRepository } from '@core/media/domain/repositories/AvatarGenerationRepository';
import { AvatarRepository } from '@core/media/domain/repositories/AvatarRepository';
import { MediaRepository } from '@core/media/domain/repositories/MediaRepository';
import type { MediaResolverPort } from '@core/ports/media/MediaResolverPort';
import type { Logger } from '@core/shared/domain/Logger';

// Import use cases
import { DeleteMediaUseCase } from '@core/media/application/use-cases/DeleteMediaUseCase';
import { GetAvatarUseCase } from '@core/media/application/use-cases/GetAvatarUseCase';
import { GetMediaUseCase } from '@core/media/application/use-cases/GetMediaUseCase';
import { GetUploadedMediaUseCase } from '@core/media/application/use-cases/GetUploadedMediaUseCase';
import { RequestAvatarGenerationUseCase } from '@core/media/application/use-cases/RequestAvatarGenerationUseCase';
import { ResolveMediaReferenceUseCase } from '@core/media/application/use-cases/ResolveMediaReferenceUseCase';
import { UpdateAvatarUseCase } from '@core/media/application/use-cases/UpdateAvatarUseCase';
import { UploadMediaUseCase } from '@core/media/application/use-cases/UploadMediaUseCase';

// Import presenters
import { DeleteMediaPresenter } from './presenters/DeleteMediaPresenter';
import { GetAvatarPresenter } from './presenters/GetAvatarPresenter';
import { GetMediaPresenter } from './presenters/GetMediaPresenter';
import { RequestAvatarGenerationPresenter } from './presenters/RequestAvatarGenerationPresenter';
import { UpdateAvatarPresenter } from './presenters/UpdateAvatarPresenter';
import { UploadMediaPresenter } from './presenters/UploadMediaPresenter';

import {
    AVATAR_GENERATION_PORT_TOKEN,
    AVATAR_GENERATION_REPOSITORY_TOKEN,
    AVATAR_REPOSITORY_TOKEN,
    DELETE_MEDIA_USE_CASE_TOKEN,
    FACE_VALIDATION_PORT_TOKEN,
    GET_AVATAR_USE_CASE_TOKEN,
    GET_MEDIA_USE_CASE_TOKEN,
    GET_UPLOADED_MEDIA_USE_CASE_TOKEN,
    LOGGER_TOKEN,
    MEDIA_REPOSITORY_TOKEN,
    MEDIA_RESOLVER_PORT_TOKEN,
    MEDIA_STORAGE_PORT_TOKEN,
    REQUEST_AVATAR_GENERATION_USE_CASE_TOKEN,
    RESOLVE_MEDIA_REFERENCE_USE_CASE_TOKEN,
    UPDATE_AVATAR_USE_CASE_TOKEN,
    UPLOAD_MEDIA_USE_CASE_TOKEN,
} from './MediaTokens';

export * from './MediaTokens';

import type { AvatarGenerationResult } from '@core/media/application/ports/AvatarGenerationPort';
import type { FaceValidationResult } from '@core/media/application/ports/FaceValidationPort';

// External adapters (ports) - these remain mock implementations
class MockFaceValidationAdapter implements FaceValidationPort {
  async validateFacePhoto(): Promise<FaceValidationResult> {
    return {
      isValid: true,
      hasFace: true,
      faceCount: 1,
      confidence: 0.95,
    };
  }
}

class MockAvatarGenerationAdapter implements AvatarGenerationPort {
  async generateAvatars(): Promise<AvatarGenerationResult> {
    return {
      success: true,
      avatars: [
        { url: 'https://cdn.example.com/avatars/mock-avatar-1.png' },
        { url: 'https://cdn.example.com/avatars/mock-avatar-2.png' },
        { url: 'https://cdn.example.com/avatars/mock-avatar-3.png' },
      ],
    };
  }
}

class MockLogger implements Logger {
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  debug(_message: string, _context?: unknown): void {}
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  info(_message: string, _context?: unknown): void {}
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  warn(_message: string, _context?: unknown): void {}
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
  error(_message: string, _error?: Error, _context?: unknown): void {}
}

import { MediaResolverAdapter } from '@adapters/media/MediaResolverAdapter';
import { FileSystemMediaStorageAdapter } from '@adapters/media/ports/FileSystemMediaStorageAdapter';
import { MediaGenerationService } from '@core/media/domain/services/MediaGenerationService';

// Import logging infrastructure
import { InitializationLogger } from '../../shared/logging/InitializationLogger';
import { createLoggedProviders } from '../../shared/logging/LoggedProvider';

// Initialize logger
const initLogger = InitializationLogger.getInstance();

export const MediaProviders: Provider[] = createLoggedProviders([
  MediaGenerationService,
  {
    provide: MEDIA_RESOLVER_PORT_TOKEN,
    useFactory: () => new MediaResolverAdapter({}),
  },
  RequestAvatarGenerationPresenter,
  UploadMediaPresenter,
  GetMediaPresenter,
  DeleteMediaPresenter,
  GetAvatarPresenter,
  UpdateAvatarPresenter,
  {
    provide: FACE_VALIDATION_PORT_TOKEN,
    useClass: MockFaceValidationAdapter,
  },
  {
    provide: AVATAR_GENERATION_PORT_TOKEN,
    useClass: MockAvatarGenerationAdapter,
  },
  {
    provide: MEDIA_STORAGE_PORT_TOKEN,
    useFactory: () => new FileSystemMediaStorageAdapter({
      baseDir: process.env.MEDIA_STORAGE_DIR || '/data/media',
    }),
  },
  {
    provide: LOGGER_TOKEN,
    useClass: MockLogger,
  },
  // Use cases - simplified without output ports
  {
    provide: REQUEST_AVATAR_GENERATION_USE_CASE_TOKEN,
    useFactory: (avatarRepo: AvatarGenerationRepository, faceValidation: FaceValidationPort, avatarGeneration: AvatarGenerationPort, logger: Logger) =>
      new RequestAvatarGenerationUseCase(avatarRepo, faceValidation, avatarGeneration, logger),
    inject: [AVATAR_GENERATION_REPOSITORY_TOKEN, FACE_VALIDATION_PORT_TOKEN, AVATAR_GENERATION_PORT_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: UPLOAD_MEDIA_USE_CASE_TOKEN,
    useFactory: (mediaRepo: MediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
      new UploadMediaUseCase(mediaRepo, mediaStorage, logger),
    inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: GET_MEDIA_USE_CASE_TOKEN,
    useFactory: (mediaRepo: MediaRepository, logger: Logger) =>
      new GetMediaUseCase(mediaRepo, logger),
    inject: [MEDIA_REPOSITORY_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: DELETE_MEDIA_USE_CASE_TOKEN,
    useFactory: (mediaRepo: MediaRepository, mediaStorage: MediaStoragePort, logger: Logger) =>
      new DeleteMediaUseCase(mediaRepo, mediaStorage, logger),
    inject: [MEDIA_REPOSITORY_TOKEN, MEDIA_STORAGE_PORT_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: GET_AVATAR_USE_CASE_TOKEN,
    useFactory: (avatarRepo: AvatarRepository, logger: Logger) =>
      new GetAvatarUseCase(avatarRepo, logger),
    inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: UPDATE_AVATAR_USE_CASE_TOKEN,
    useFactory: (avatarRepo: AvatarRepository, logger: Logger) =>
      new UpdateAvatarUseCase(avatarRepo, logger),
    inject: [AVATAR_REPOSITORY_TOKEN, LOGGER_TOKEN],
  },
  {
    provide: RESOLVE_MEDIA_REFERENCE_USE_CASE_TOKEN,
    useFactory: (mediaResolver: MediaResolverPort) =>
      new ResolveMediaReferenceUseCase(mediaResolver),
    inject: [MEDIA_RESOLVER_PORT_TOKEN],
  },
  {
    provide: GET_UPLOADED_MEDIA_USE_CASE_TOKEN,
    useFactory: (mediaStorage: MediaStoragePort) =>
      new GetUploadedMediaUseCase(mediaStorage),
    inject: [MEDIA_STORAGE_PORT_TOKEN],
  },
], initLogger);
