const express = require('express');
const router = express.Router();
const path = require('path');
const fs = require('fs');
const multer = require('multer');
const bannersRouter = require('./banners');
const uploadRouter = require('./upload');
const prescriptionsRouter = require('./prescriptions');

// Import middleware
const { auth, authorize } = require('../middleware/auth');
const { validate } = require('../middleware/validation');
const { catchAsync } = require('../middleware/errorHandler');

// Import controllers
const authController = require('../controllers/authController');
const usersController = require('../controllers/usersController');
const addressesController = require('../controllers/addressesController');
const userAddressesController = require('../controllers/userAddressesController');
const categoriesController = require('../controllers/categoriesController');
const brandsController = require('../controllers/brandsController');
const itemsController = require('../controllers/itemsController');

// Import route files
const itemsRouter = require('./items');
const storesRouter = require('./stores');
const ordersRouter = require('./orders');
const orderItemsController = require('../controllers/orderItemsController');
const orderStatusHistoryController = require('../controllers/orderStatusHistoryController');
const deliveryBoysController = require('../controllers/deliveryBoysController');
const storesController = require('../controllers/storesController');
const discountsController = require('../controllers/discountsController');
const taxesController = require('../controllers/taxesController');
const unitsController = require('../controllers/unitsController');
const pharmacistRouter = require('./pharmacists');
const customersRouter = require('./customers');
const bonusesRouter = require('./bonuses');
const fundsTransferRouter = require('./fundsTransfer');
const cashCollectionRouter = require('./cashCollection');
const settingsRouter = require('./settings');
const webSettingsRouter = require('./webSettings');
const returnsRouter = require('./returns');
const refundsRouter = require('./refunds');
const homepageSectionsRoutes = require('./homepageSections');
const categoriesRouter = require('./categories');
const addressRouter = require('./addresses');
const reportsRouter = require('./reports');
const couponsRouter = require('./coupons');

// Import upload middleware
const { uploadBrandImage, handleUploadError } = require('../middleware/upload');
const { 
  registerRules, 
  loginRules, 
  updateProfileRules, 
  addressRules,
  itemRules,
  orderRules,
  prescriptionRules
} = require('../middleware/validation');

// Auth routes
router.post('/auth/register', catchAsync(authController.register));
router.post('/auth/login', catchAsync(authController.login));
router.get('/auth/me', auth, catchAsync(authController.getMe));
router.post('/auth/forgot-password', catchAsync(authController.forgotPassword));
router.post('/auth/reset-password/:token', catchAsync(authController.resetPassword));

// User routes
// @desc    Get current user's profile
// @route   GET /api/users/me
// @access  Private
router.get('/users/me', auth, catchAsync(usersController.getProfile));

// @desc    Update user profile
// @route   PUT /api/users/me
// @access  Private
router.put('/users/me', auth, validate(updateProfileRules()), catchAsync(usersController.updateProfile));

// @desc    Update user's password
// @route   PUT /api/users/me/password
// @access  Private
router.put('/users/me/password', auth, catchAsync(usersController.updatePassword));

// Address routes
// @desc    Get user's addresses
// @route   GET /api/users/me/addresses
// @access  Private
router.get('/users/me/addresses', auth, (req, res, next) => {
  // Set the userId in params to the current user's ID
  req.params.userId = req.user.id;
  next();
}, catchAsync(userAddressesController.getUserAddresses));

// @desc    Add new address
// @route   POST /api/users/me/addresses
// @access  Private
router.post('/users/me/addresses', auth, validate(addressRules()), (req, res, next) => {
  // Set the userId in params to the current user's ID
  req.params.userId = req.user.id;
  next();
}, catchAsync(userAddressesController.addUserAddress));

// @desc    Update address
// @route   PUT /api/users/me/addresses/:addressId
// @access  Private
router.put('/users/me/addresses/:addressId', auth, validate(addressRules()), catchAsync(userAddressesController.updateUserAddress));

// @desc    Delete address
// @route   DELETE /api/users/me/addresses/:addressId
// @access  Private
router.delete('/users/me/addresses/:addressId', auth, catchAsync(userAddressesController.deleteUserAddress));

// @desc    Set default address
// @route   PUT /api/users/me/addresses/:addressId/set-default
// @desc    Get default address
// @route   GET /api/users/me/addresses/default
// @access  Private
router.get('/users/me/addresses/default', auth, catchAsync(userAddressesController.getDefaultAddress));

// Mount route files
router.use('/items', itemsRouter);
router.use('/stores', storesRouter);
router.use('/orders', ordersRouter);
router.use('/prescriptions', prescriptionsRouter);
router.use('/customers', customersRouter);
router.use('/bonuses', bonusesRouter);
router.use('/funds-transfer', fundsTransferRouter);
router.use('/cash-collection', cashCollectionRouter);
router.use('/settings', settingsRouter);
router.use('/web-settings', webSettingsRouter);
router.use('/returns', returnsRouter);

// Mount upload router under /v1/upload
router.use('/v1/upload', uploadRouter);
router.use('/refunds', refundsRouter);
router.use('/homepage-sections', homepageSectionsRoutes);
router.use('/categories', categoriesRouter);
router.use('/addresses', addressRouter);
router.use('/banners', bannersRouter);
router.use('/reports', reportsRouter);
router.use('/coupons', couponsRouter);
router.use('/discounts', require('./discounts'));

// Mount pharmacists routes
router.use('/pharmacists', require('./pharmacists'));

router.use('/picker-packers', require('./pickerPacker'));

// Ensure category upload directory exists
const categoryUploadDir = path.join(__dirname, '../uploads/categories');
if (!fs.existsSync(categoryUploadDir)) {
  fs.mkdirSync(categoryUploadDir, { recursive: true });
}

// Configure multer for category uploads
const categoryStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, categoryUploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, 'category-' + uniqueSuffix + path.extname(file.originalname));
  }
});

const categoryFileFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image/')) {
    cb(null, true);
  } else {
    cb(new Error('Only image files are allowed!'), false);
  }
};

const uploadCategoryImage = multer({
  storage: categoryStorage,
  limits: {
    fileSize: 5 * 1024 * 1024 // 5MB limit
  },
  fileFilter: categoryFileFilter
});

// Categories routes
router.get('/categories', catchAsync(categoriesController.getAllCategories));
router.get('/categories/search', catchAsync(categoriesController.searchCategories));
router.get('/categories/analytics/statistics', auth, authorize('admin'), catchAsync(categoriesController.getCategoryStatistics));
router.get('/categories/:id', catchAsync(categoriesController.getCategoryById));
router.post('/categories', auth, authorize('admin'), uploadCategoryImage.single('image'), catchAsync(categoriesController.createCategory));
router.put('/categories/:id', auth, authorize('admin'), uploadCategoryImage.single('image'), catchAsync(categoriesController.updateCategory));
router.patch('/categories/:id/toggle-status', auth, authorize('admin'), catchAsync(categoriesController.toggleCategoryStatus));
router.delete('/categories/:id', auth, authorize('admin'), catchAsync(categoriesController.deleteCategory));

// Brands routes
router.get('/brands', catchAsync(brandsController.getAllBrands));
router.get('/brands/:id', catchAsync(brandsController.getBrandById));
router.post('/brands', auth, authorize('admin'), uploadBrandImage, handleUploadError, catchAsync(brandsController.createBrand));
router.put('/brands/:id', auth, authorize('admin'), uploadBrandImage, handleUploadError, catchAsync(brandsController.updateBrand));
router.patch('/brands/:id/toggle-status', auth, authorize('admin'), catchAsync(brandsController.toggleBrandStatus));
router.delete('/brands/:id', auth, authorize('admin'), catchAsync(brandsController.deleteBrand));

// Brand Search and Filter Routes
router.get('/brands/search', catchAsync(brandsController.searchBrands));
router.get('/brands/company/:companyName', catchAsync(brandsController.getBrandsByCompany));

// Brand Analytics Routes
router.get('/brands/analytics/item-counts', auth, authorize('admin'), catchAsync(brandsController.getBrandsWithItemCounts));
router.get('/brands/statistics', auth, authorize('admin'), catchAsync(brandsController.getBrandStatistics));
router.get('/brands/needing-attention', auth, authorize('admin'), catchAsync(brandsController.getBrandsNeedingAttention));

// Orders routes
router.use('/orders', ordersRouter);

// Order items routes
router.get('/orders/:orderId/items', auth, catchAsync(orderItemsController.getOrderItems));
router.get('/orders/items/:id', auth, catchAsync(orderItemsController.getOrderItemById));
router.post('/orders/:orderId/items', auth, catchAsync(orderItemsController.addOrderItem));
router.put('/orders/items/:id', auth, catchAsync(orderItemsController.updateOrderItem));
router.delete('/orders/items/:id', auth, catchAsync(orderItemsController.deleteOrderItem));

// Order status history routes
router.get('/orders/:orderId/status-history', auth, catchAsync(orderStatusHistoryController.getOrderStatusHistory));

// Delivery boys routes
router.get('/delivery-boys', auth, authorize('admin'), catchAsync(deliveryBoysController.getAllDeliveryBoys));
router.get('/delivery-boys/available', auth, authorize('admin'), catchAsync(deliveryBoysController.getAvailableDeliveryBoys));
router.get('/delivery-boys/:id', auth, authorize('admin'), catchAsync(deliveryBoysController.getDeliveryBoyById));
router.post('/delivery-boys', auth, authorize('admin'), catchAsync(deliveryBoysController.createDeliveryBoy));
router.put('/delivery-boys/:id', auth, authorize('admin'), catchAsync(deliveryBoysController.updateDeliveryBoy));
router.put('/delivery-boys/:id/status', auth, authorize('admin'), catchAsync(deliveryBoysController.updateDeliveryBoyStatus));
router.delete('/delivery-boys/:id', auth, authorize('admin'), catchAsync(deliveryBoysController.deleteDeliveryBoy));
router.get('/delivery-boys/:id/earnings', auth, catchAsync(deliveryBoysController.getDeliveryBoyEarnings));
router.get('/delivery-boys/:id/orders', auth, catchAsync(deliveryBoysController.getDeliveryBoyOrders));
router.patch('/delivery-boys/:id/availability', auth, authorize('admin'), catchAsync(deliveryBoysController.updateDeliveryBoyAvailability));

// Store upload configuration
const storeUploadDir = path.join(__dirname, '../uploads/stores');
if (!fs.existsSync(storeUploadDir)) {
  fs.mkdirSync(storeUploadDir, { recursive: true });
}

const storeStorage = multer.diskStorage({
  destination: (req, file, cb) => {
    cb(null, storeUploadDir);
  },
  filename: (req, file, cb) => {
    const uniqueSuffix = Date.now() + '-' + Math.round(Math.random() * 1E9);
    cb(null, 'store-' + uniqueSuffix + path.extname(file.originalname));
  }
});

const storeFileFilter = (req, file, cb) => {
  if (file.mimetype.startsWith('image/') || file.mimetype === 'application/pdf') {
    cb(null, true);
  } else {
    cb(new Error('Only image files and PDFs are allowed!'), false);
  }
};

const uploadStoreFiles = multer({
  storage: storeStorage,
  limits: {
    fileSize: 10 * 1024 * 1024 // 10MB limit
  },
  fileFilter: storeFileFilter
});

// Stores routes
router.get('/stores', catchAsync(storesController.getAllStores));
router.get('/stores/search', catchAsync(storesController.searchStores));
router.get('/stores/analytics/statistics', auth, authorize('admin'), catchAsync(storesController.getStoreStatistics));
router.get('/stores/city/:city', catchAsync(storesController.getStoresByCity));
router.get('/stores/:id', catchAsync(storesController.getStoreById));
router.post('/stores', auth, authorize('admin'), uploadStoreFiles.fields([
  { name: 'logo', maxCount: 1 },
  { name: 'nationalIdCard', maxCount: 1 },
  { name: 'addressProof', maxCount: 1 }
]), catchAsync(storesController.createStore));
router.put('/stores/:id', auth, authorize('admin'), uploadStoreFiles.fields([
  { name: 'logo', maxCount: 1 },
  { name: 'nationalIdCard', maxCount: 1 },
  { name: 'addressProof', maxCount: 1 }
]), catchAsync(storesController.updateStore));
router.patch('/stores/:id/toggle-status', auth, authorize('admin'), catchAsync(storesController.toggleStoreStatus));
router.delete('/stores/:id', auth, authorize('admin'), catchAsync(storesController.deleteStore));

// Discounts routes are now in a separate file (discounts.js)

// Taxes routes
router.get('/taxes', catchAsync(taxesController.getAllTaxes));
router.get('/taxes/search', catchAsync(taxesController.searchTaxes));
router.get('/taxes/analytics/statistics', auth, authorize('admin'), catchAsync(taxesController.getTaxStatistics));
router.get('/taxes/active', catchAsync(taxesController.getActiveTaxes));
router.get('/taxes/:id', catchAsync(taxesController.getTaxById));
router.post('/taxes', auth, authorize('admin'), catchAsync(taxesController.createTax));
router.put('/taxes/:id', auth, authorize('admin'), catchAsync(taxesController.updateTax));
router.patch('/taxes/:id/toggle-status', auth, authorize('admin'), catchAsync(taxesController.toggleTaxStatus));
router.delete('/taxes/:id', auth, authorize('admin'), catchAsync(taxesController.deleteTax));

// Units routes
router.get('/units', catchAsync(unitsController.getAllUnits));
router.get('/units/search', catchAsync(unitsController.searchUnits));
router.get('/units/analytics/statistics', auth, authorize('admin'), catchAsync(unitsController.getUnitStatistics));
router.get('/units/:id', catchAsync(unitsController.getUnitById));
router.post('/units', auth, authorize('admin'), catchAsync(unitsController.createUnit));
router.put('/units/:id', auth, authorize('admin'), catchAsync(unitsController.updateUnit));
router.patch('/units/:id/toggle-status', auth, authorize('admin'), catchAsync(unitsController.toggleUnitStatus));
router.delete('/units/:id', auth, authorize('admin'), catchAsync(unitsController.deleteUnit));

// Customers routes
router.use('/customers', customersRouter);

module.exports = router;
