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

import type { IArticlesRepository } from "../application/repositories/articles.repository.interface";
import { MockArticlesRepository } from "../infrastructure/repositories/articles.repository.mock";
import {
  getArticlesUseCase,
  type IGetArticlesUseCase,
} from "../application/use-cases/get-articles.use-case";
import {
  createArticleUseCase,
  type ICreateArticleUseCase,
} from "../application/use-cases/create-article.use-case";
import {
  getArticleBySlugUseCase,
  type IGetArticleBySlugUseCase,
} from "../application/use-cases/get-article-by-slug.use-case";
import {
  getArticlesController,
  type IGetArticlesController,
} from "../interface-adapters/controllers/get-articles.controller";
import {
  createArticleController,
  type ICreateArticleController,
} from "../interface-adapters/controllers/create-article.controller";
import {
  getArticleBySlugController,
  type IGetArticleBySlugController,
} from "../interface-adapters/controllers/get-article-by-slug.controller";
import { BLOG_SYMBOLS } from "./symbols";

export const BlogModule = new ContainerModule((bind: interfaces.Bind) => {
  bind<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository).to(MockArticlesRepository);

  bind<IGetArticlesUseCase>(BLOG_SYMBOLS.IGetArticlesUseCase).toDynamicValue((ctx) =>
    getArticlesUseCase(
      ctx.container.get<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository),
    ),
  );

  bind<ICreateArticleUseCase>(BLOG_SYMBOLS.ICreateArticleUseCase).toDynamicValue((ctx) =>
    createArticleUseCase(
      ctx.container.get<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository),
    ),
  );

  bind<IGetArticleBySlugUseCase>(BLOG_SYMBOLS.IGetArticleBySlugUseCase).toDynamicValue((ctx) =>
    getArticleBySlugUseCase(
      ctx.container.get<IArticlesRepository>(BLOG_SYMBOLS.IArticlesRepository),
    ),
  );

  bind<IGetArticlesController>(BLOG_SYMBOLS.IGetArticlesController).toDynamicValue((ctx) =>
    getArticlesController(
      ctx.container.get<IGetArticlesUseCase>(BLOG_SYMBOLS.IGetArticlesUseCase),
    ),
  );

  bind<ICreateArticleController>(BLOG_SYMBOLS.ICreateArticleController).toDynamicValue((ctx) =>
    createArticleController(
      ctx.container.get<ICreateArticleUseCase>(BLOG_SYMBOLS.ICreateArticleUseCase),
    ),
  );

  bind<IGetArticleBySlugController>(BLOG_SYMBOLS.IGetArticleBySlugController).toDynamicValue((ctx) =>
    getArticleBySlugController(
      ctx.container.get<IGetArticleBySlugUseCase>(BLOG_SYMBOLS.IGetArticleBySlugUseCase),
    ),
  );
});
