/**
 * CoreController - Unified Core Module REST API
 *
 * Provides REST endpoints for core shared functionality:
 * - Sequences (document number generation)
 * - Currencies and exchange rates
 * - Units of measure
 * - Payment terms
 * - Geography (countries/states)
 * - Product categories
 *
 * @module Core
 * @prefix /api/v1/core
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import {
  SequenceService,
  CurrencyService,
  UomService,
  PaymentTermService,
  GeographyService,
  ProductCategoryService,
  SequenceFilters,
  CurrencyRateFilters,
  UomFilters,
  PaymentTermFilters,
  StateFilters,
  ProductCategoryFilters,
} from '../services';
import {
  Sequence,
  Currency,
  CurrencyRate,
  Uom,
  UomCategory,
  PaymentTerm,
  PaymentTermLine,
  Country,
  State,
  ProductCategory,
} from '../entities';
import { AuthMiddleware } from '../../auth/middleware/auth.middleware';
import { AuthService } from '../../auth/services/auth.service';
import { User } from '../entities/user.entity';
import { Tenant } from '../entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';

interface ServiceContext {
  tenantId: string;
  userId?: string;
}

export function createCoreController(dataSource: DataSource): Router {
  const router = Router();

  // Repositories
  const sequenceRepository = dataSource.getRepository(Sequence);
  const currencyRepository = dataSource.getRepository(Currency);
  const currencyRateRepository = dataSource.getRepository(CurrencyRate);
  const uomRepository = dataSource.getRepository(Uom);
  const uomCategoryRepository = dataSource.getRepository(UomCategory);
  const paymentTermRepository = dataSource.getRepository(PaymentTerm);
  const paymentTermLineRepository = dataSource.getRepository(PaymentTermLine);
  const countryRepository = dataSource.getRepository(Country);
  const stateRepository = dataSource.getRepository(State);
  const productCategoryRepository = dataSource.getRepository(ProductCategory);
  const userRepository = dataSource.getRepository(User);
  const tenantRepository = dataSource.getRepository(Tenant);
  const refreshTokenRepository = dataSource.getRepository(RefreshToken);

  // Services
  const sequenceService = new SequenceService(sequenceRepository, dataSource);
  const currencyService = new CurrencyService(currencyRepository, currencyRateRepository);
  const uomService = new UomService(uomCategoryRepository, uomRepository);
  const paymentTermService = new PaymentTermService(paymentTermRepository, paymentTermLineRepository);
  const geographyService = new GeographyService(countryRepository, stateRepository);
  const productCategoryService = new ProductCategoryService(productCategoryRepository);
  const authService = new AuthService(userRepository, tenantRepository, refreshTokenRepository as any);
  const authMiddleware = new AuthMiddleware(authService, dataSource);

  // Helper to create service context
  const getContext = (req: Request): ServiceContext => {
    if (!req.tenantId) {
      throw new Error('Tenant ID is required');
    }
    return {
      tenantId: req.tenantId,
      userId: req.user?.sub,
    };
  };

  // ==================== SEQUENCES ====================

  /**
   * GET /core/sequences
   * List all sequences
   */
  router.get('/sequences', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: SequenceFilters = {};
      if (req.query.code) filters.code = req.query.code as string;
      if (req.query.isActive !== undefined) filters.isActive = req.query.isActive === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await sequenceService.findWithFilters(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/sequences/:id
   * Get sequence by ID
   */
  router.get('/sequences/:id', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const sequence = await sequenceService.findById(ctx, req.params.id);

      if (!sequence) {
        res.status(404).json({ error: 'Not Found', message: 'Sequence not found' });
        return;
      }

      res.status(200).json({ success: true, data: sequence });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/sequences/code/:code/next
   * Get next sequence number
   */
  router.get('/sequences/code/:code/next', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const number = await sequenceService.getNextNumber(ctx, req.params.code);
      res.status(200).json({ success: true, data: { number } });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/sequences/code/:code/preview
   * Preview next sequence number without incrementing
   */
  router.get('/sequences/code/:code/preview', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const number = await sequenceService.previewNextNumber(ctx, req.params.code);
      res.status(200).json({ success: true, data: { number } });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/sequences
   * Create sequence
   */
  router.post('/sequences', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const sequence = await sequenceService.create(ctx, req.body);
      res.status(201).json({ success: true, data: sequence });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /core/sequences/:id
   * Update sequence
   */
  router.put('/sequences/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const sequence = await sequenceService.update(ctx, req.params.id, req.body);

      if (!sequence) {
        res.status(404).json({ error: 'Not Found', message: 'Sequence not found' });
        return;
      }

      res.status(200).json({ success: true, data: sequence });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/sequences/code/:code/reset
   * Reset sequence to starting number
   */
  router.post('/sequences/code/:code/reset', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const startNumber = parseInt(req.body.startNumber as string) || 1;
      const sequence = await sequenceService.resetSequence(ctx, req.params.code, startNumber);

      if (!sequence) {
        res.status(404).json({ error: 'Not Found', message: 'Sequence not found' });
        return;
      }

      res.status(200).json({ success: true, data: sequence });
    } catch (error) {
      next(error);
    }
  });

  // ==================== CURRENCIES ====================

  /**
   * GET /core/currencies
   * List all currencies
   */
  router.get('/currencies', async (_req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const currencies = await currencyService.findAllCurrencies();
      res.status(200).json({ success: true, data: currencies });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/currencies/:id
   * Get currency by ID
   */
  router.get('/currencies/:id', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const currency = await currencyService.findCurrencyById(req.params.id);

      if (!currency) {
        res.status(404).json({ error: 'Not Found', message: 'Currency not found' });
        return;
      }

      res.status(200).json({ success: true, data: currency });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/currencies/code/:code
   * Get currency by code
   */
  router.get('/currencies/code/:code', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const currency = await currencyService.findCurrencyByCode(req.params.code);

      if (!currency) {
        res.status(404).json({ error: 'Not Found', message: 'Currency not found' });
        return;
      }

      res.status(200).json({ success: true, data: currency });
    } catch (error) {
      next(error);
    }
  });

  // ==================== EXCHANGE RATES ====================

  /**
   * GET /core/exchange-rates
   * Get exchange rate history
   */
  router.get('/exchange-rates', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: CurrencyRateFilters = {};
      if (req.query.fromCurrencyId) filters.fromCurrencyId = req.query.fromCurrencyId as string;
      if (req.query.toCurrencyId) filters.toCurrencyId = req.query.toCurrencyId as string;
      if (req.query.source) filters.source = req.query.source as any;

      const result = await currencyService.getRateHistory(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/exchange-rates/latest
   * Get latest exchange rates
   */
  router.get('/exchange-rates/latest', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const rates = await currencyService.getLatestRates(ctx);
      res.status(200).json({ success: true, data: rates });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/exchange-rates
   * Create exchange rate
   */
  router.post('/exchange-rates', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const rate = await currencyService.createRate(ctx, req.body);
      res.status(201).json({ success: true, data: rate });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/exchange-rates/convert
   * Convert amount between currencies
   */
  router.post('/exchange-rates/convert', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { amount, fromCurrencyCode, toCurrencyCode, date } = req.body;

      if (!amount || !fromCurrencyCode || !toCurrencyCode) {
        res.status(400).json({ error: 'Bad Request', message: 'amount, fromCurrencyCode, and toCurrencyCode are required' });
        return;
      }

      const result = await currencyService.convertByCode(
        ctx,
        parseFloat(amount),
        fromCurrencyCode,
        toCurrencyCode,
        date ? new Date(date) : undefined
      );

      res.status(200).json({ success: true, data: result });
    } catch (error) {
      next(error);
    }
  });

  // ==================== UNITS OF MEASURE ====================

  /**
   * GET /core/uom-categories
   * List all UoM categories
   */
  router.get('/uom-categories', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const categories = await uomService.findAllCategories(ctx);
      res.status(200).json({ success: true, data: categories });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/uom-categories
   * Create UoM category
   */
  router.post('/uom-categories', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const category = await uomService.createCategory(ctx, req.body);
      res.status(201).json({ success: true, data: category });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * GET /core/uom
   * List all units of measure
   */
  router.get('/uom', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: UomFilters = {};
      if (req.query.categoryId) filters.categoryId = req.query.categoryId as string;
      if (req.query.active !== undefined) filters.active = req.query.active === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await uomService.findWithFilters(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/uom
   * Create unit of measure
   */
  router.post('/uom', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const uom = await uomService.create(ctx, req.body);
      res.status(201).json({ success: true, data: uom });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * POST /core/uom/convert
   * Convert quantity between UoMs
   */
  router.post('/uom/convert', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { quantity, fromUomId, toUomId } = req.body;

      if (quantity === undefined || !fromUomId || !toUomId) {
        res.status(400).json({ error: 'Bad Request', message: 'quantity, fromUomId, and toUomId are required' });
        return;
      }

      const result = await uomService.convert(ctx, parseFloat(quantity), fromUomId, toUomId);
      res.status(200).json({ success: true, data: result });
    } catch (error) {
      next(error);
    }
  });

  // ==================== PAYMENT TERMS ====================

  /**
   * GET /core/payment-terms
   * List all payment terms
   */
  router.get('/payment-terms', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: PaymentTermFilters = {};
      if (req.query.code) filters.code = req.query.code as string;
      if (req.query.isActive !== undefined) filters.isActive = req.query.isActive === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await paymentTermService.findWithFilters(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/payment-terms/:id
   * Get payment term by ID
   */
  router.get('/payment-terms/:id', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const term = await paymentTermService.findById(ctx, req.params.id);

      if (!term) {
        res.status(404).json({ error: 'Not Found', message: 'Payment term not found' });
        return;
      }

      res.status(200).json({ success: true, data: term });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/payment-terms
   * Create payment term
   */
  router.post('/payment-terms', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const term = await paymentTermService.create(ctx, req.body);
      res.status(201).json({ success: true, data: term });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /core/payment-terms/:id
   * Update payment term
   */
  router.put('/payment-terms/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const term = await paymentTermService.update(ctx, req.params.id, req.body);

      if (!term) {
        res.status(404).json({ error: 'Not Found', message: 'Payment term not found' });
        return;
      }

      res.status(200).json({ success: true, data: term });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/payment-terms/:id/calculate-schedule
   * Calculate payment schedule for an invoice
   */
  router.post('/payment-terms/:id/calculate-schedule', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const { invoiceDate, totalAmount } = req.body;

      if (!invoiceDate || !totalAmount) {
        res.status(400).json({ error: 'Bad Request', message: 'invoiceDate and totalAmount are required' });
        return;
      }

      const schedule = await paymentTermService.generatePaymentSchedule(
        ctx,
        req.params.id,
        new Date(invoiceDate),
        parseFloat(totalAmount)
      );

      res.status(200).json({ success: true, data: schedule });
    } catch (error) {
      next(error);
    }
  });

  // ==================== GEOGRAPHY ====================

  /**
   * GET /core/countries
   * List all countries
   */
  router.get('/countries', async (_req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const countries = await geographyService.findAllCountries();
      res.status(200).json({ success: true, data: countries });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/countries/:id
   * Get country by ID
   */
  router.get('/countries/:id', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const country = await geographyService.findCountryById(req.params.id);

      if (!country) {
        res.status(404).json({ error: 'Not Found', message: 'Country not found' });
        return;
      }

      res.status(200).json({ success: true, data: country });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/countries/code/:code
   * Get country by code
   */
  router.get('/countries/code/:code', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const country = await geographyService.findCountryByCode(req.params.code);

      if (!country) {
        res.status(404).json({ error: 'Not Found', message: 'Country not found' });
        return;
      }

      res.status(200).json({ success: true, data: country });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/states
   * List states with filters
   */
  router.get('/states', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: StateFilters = {};
      if (req.query.countryId) filters.countryId = req.query.countryId as string;
      if (req.query.countryCode) filters.countryCode = req.query.countryCode as string;
      if (req.query.isActive !== undefined) filters.isActive = req.query.isActive === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await geographyService.findStatesWithFilters(filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/states/country/:countryCode
   * Get states by country code
   */
  router.get('/states/country/:countryCode', async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const states = await geographyService.findStatesByCountryCode(req.params.countryCode);
      res.status(200).json({ success: true, data: states });
    } catch (error) {
      next(error);
    }
  });

  // ==================== PRODUCT CATEGORIES ====================

  /**
   * GET /core/product-categories
   * List product categories
   */
  router.get('/product-categories', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 100);

      const filters: ProductCategoryFilters = {};
      if (req.query.parentId === 'null') {
        filters.parentId = null;
      } else if (req.query.parentId) {
        filters.parentId = req.query.parentId as string;
      }
      if (req.query.active !== undefined) filters.active = req.query.active === 'true';
      if (req.query.search) filters.search = req.query.search as string;

      const result = await productCategoryService.findWithFilters(ctx, filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: {
          total: result.total,
          page: result.page,
          limit: result.limit,
          totalPages: result.totalPages,
        },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/product-categories/tree
   * Get category tree
   */
  router.get('/product-categories/tree', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const tree = await productCategoryService.getCategoryTree(ctx);
      res.status(200).json({ success: true, data: tree });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/product-categories/flat
   * Get flattened category tree (for dropdowns)
   */
  router.get('/product-categories/flat', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const categories = await productCategoryService.getFlattenedTree(ctx);
      res.status(200).json({ success: true, data: categories });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /core/product-categories/:id
   * Get category by ID
   */
  router.get('/product-categories/:id', authMiddleware.authenticate, async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const category = await productCategoryService.findById(ctx, req.params.id);

      if (!category) {
        res.status(404).json({ error: 'Not Found', message: 'Category not found' });
        return;
      }

      res.status(200).json({ success: true, data: category });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /core/product-categories
   * Create category
   */
  router.post('/product-categories', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const category = await productCategoryService.create(ctx, req.body);
      res.status(201).json({ success: true, data: category });
    } catch (error) {
      if (error instanceof Error && error.message.includes('already exists')) {
        res.status(409).json({ error: 'Conflict', message: error.message });
        return;
      }
      next(error);
    }
  });

  /**
   * PUT /core/product-categories/:id
   * Update category
   */
  router.put('/product-categories/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const category = await productCategoryService.update(ctx, req.params.id, req.body);

      if (!category) {
        res.status(404).json({ error: 'Not Found', message: 'Category not found' });
        return;
      }

      res.status(200).json({ success: true, data: category });
    } catch (error) {
      next(error);
    }
  });

  /**
   * DELETE /core/product-categories/:id
   * Delete category
   */
  router.delete('/product-categories/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const ctx = getContext(req);
      const deleted = await productCategoryService.delete(ctx, req.params.id);

      if (!deleted) {
        res.status(404).json({ error: 'Not Found', message: 'Category not found' });
        return;
      }

      res.status(200).json({ success: true, message: 'Category deleted' });
    } catch (error) {
      if (error instanceof Error && error.message.includes('Cannot delete')) {
        res.status(400).json({ error: 'Bad Request', message: error.message });
        return;
      }
      next(error);
    }
  });

  return router;
}

export default createCoreController;
