import { ContainerModule, type interfaces } from "inversify";

import type { IMediaRepository } from "../application/repositories/media.repository.interface";
import { MockMediaRepository } from "../infrastructure/repositories/media.repository.mock";
import {
  getMediaUseCase,
  type IGetMediaUseCase,
} from "../application/use-cases/get-media.use-case";
import {
  listMediaUseCase,
  type IListMediaUseCase,
} from "../application/use-cases/list-media.use-case";
import {
  deleteMediaUseCase,
  type IDeleteMediaUseCase,
} from "../application/use-cases/delete-media.use-case";
import {
  getMediaController,
  type IGetMediaController,
} from "../interface-adapters/controllers/get-media.controller";
import {
  listMediaController,
  type IListMediaController,
} from "../interface-adapters/controllers/list-media.controller";
import {
  deleteMediaController,
  type IDeleteMediaController,
} from "../interface-adapters/controllers/delete-media.controller";
import { MEDIA_SYMBOLS } from "./symbols";

export const MediaModule = new ContainerModule((bind: interfaces.Bind) => {
  bind<IMediaRepository>(MEDIA_SYMBOLS.IMediaRepository).to(MockMediaRepository);

  bind<IGetMediaUseCase>(MEDIA_SYMBOLS.IGetMediaUseCase).toDynamicValue((ctx) =>
    getMediaUseCase(
      ctx.container.get<IMediaRepository>(MEDIA_SYMBOLS.IMediaRepository),
    ),
  );

  bind<IListMediaUseCase>(MEDIA_SYMBOLS.IListMediaUseCase).toDynamicValue((ctx) =>
    listMediaUseCase(
      ctx.container.get<IMediaRepository>(MEDIA_SYMBOLS.IMediaRepository),
    ),
  );

  bind<IDeleteMediaUseCase>(MEDIA_SYMBOLS.IDeleteMediaUseCase).toDynamicValue((ctx) =>
    deleteMediaUseCase(
      ctx.container.get<IMediaRepository>(MEDIA_SYMBOLS.IMediaRepository),
    ),
  );

  bind<IGetMediaController>(MEDIA_SYMBOLS.IGetMediaController).toDynamicValue((ctx) =>
    getMediaController(
      ctx.container.get<IGetMediaUseCase>(MEDIA_SYMBOLS.IGetMediaUseCase),
    ),
  );

  bind<IListMediaController>(MEDIA_SYMBOLS.IListMediaController).toDynamicValue((ctx) =>
    listMediaController(
      ctx.container.get<IListMediaUseCase>(MEDIA_SYMBOLS.IListMediaUseCase),
    ),
  );

  bind<IDeleteMediaController>(MEDIA_SYMBOLS.IDeleteMediaController).toDynamicValue((ctx) =>
    deleteMediaController(
      ctx.container.get<IDeleteMediaUseCase>(MEDIA_SYMBOLS.IDeleteMediaUseCase),
    ),
  );
});
