import { Router } from 'express';
import { Controllers } from './controllers.factory';
import { Middlewares } from './middleware.factory';
import { createDeviceRoutes } from '../../interface/routes/device.routes';
import { createWalletRoutes } from '../../interface/routes/wallet.routes';
import { createNetworkRoutes } from '../../interface/routes/network.routes';
import { createTokenRoutes } from '../../interface/routes/token.routes';
import { createBalanceRoutes } from '../../interface/routes/balance.routes';
import { createTransactionRoutes } from '../../interface/routes/transaction.routes';
import { createAdminRoutes } from '../../interface/routes/admin.routes';
import { createImageRoutes } from '../../interface/routes/image.routes';
import { createAddressRoutes } from '../../interface/routes/address.routes';

export interface Routes {
  apiRouter: Router;
  imageRouter: Router;
}

/**
 * Compose all resource routers.
 *
 * - `apiRouter` contains the authenticated/public API endpoints under `/api/v1`.
 * - `imageRouter` contains the public image serving endpoint under `/images`.
 *
 * @param controllers - All HTTP controllers created by the composition root.
 * @param middlewares - Shared middlewares including the strict rate limiter.
 * @returns Both routers to be mounted by `createApp`.
 */
export const createRoutes = (controllers: Controllers, middlewares: Middlewares): Routes => {
  const apiRouter = Router();

  apiRouter.use(createDeviceRoutes(controllers.deviceController));
  apiRouter.use(createWalletRoutes(controllers.walletController, middlewares.strictRateLimiter));
  apiRouter.use(createNetworkRoutes(controllers.networkController));
  apiRouter.use(createTokenRoutes(controllers.tokenController));
  apiRouter.use(createBalanceRoutes(controllers.balanceController));
  apiRouter.use(createTransactionRoutes(controllers.transactionController));
  apiRouter.use(createAddressRoutes(controllers.addressController));
  apiRouter.use(createAdminRoutes(controllers.adminController));

  const imageRouter = createImageRoutes(controllers.imageController);

  return { apiRouter, imageRouter };
};
