import express, { Router } from 'express';

import * as projectValidation from '@/modules/project/project.validation';
import * as projectController from '@/modules/project/project.controller';
import * as unitValidation from '@/modules/project/unit/unit.validation';
import * as unitController from '@/modules/project/unit/unit.controller';

import { validateMiddleware } from '@/shared/utils/middlewares/index';
import userAuthAndCheckPermissions from '@/modules/auth/auth.user.middleware';
import { setAuditFields } from '@/shared/middleware/setAuditFields';
import { AuditMode } from '@/shared/constants/enum.constant';
import upload from '@/shared/utils/middlewares/upload.middleware';
import paymentTermRoutes from './paymentTerms/paymentTerms.route';
import timelineRoutes from './timeline/timeline.route';
import fileRoutes from './files/files.route';
import unitJobRoutes from './unit/job/unit-job.route';
import { MODULE_LIST } from '@/shared/constants/module.constant';
import { ACTIONS } from '@/shared/constants';

const router: Router = express.Router();
router.use('/:projectId/units/jobs', unitJobRoutes);
router
  .route('/')
  .get(
    userAuthAndCheckPermissions(),
    validateMiddleware(projectValidation.getProjects),
    projectController.getProjects,
  )
  .post(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.CREATE),
    validateMiddleware(projectValidation.createProject()),
    setAuditFields({ mode: AuditMode.CREATE }),
    projectController.createProject,
  );

router
  .route('/search')
  .get(
    userAuthAndCheckPermissions(),
    validateMiddleware(projectValidation.searchProjects),
    projectController.searchProjects,
  );

router
  .route('/analytics')
  .get(
    userAuthAndCheckPermissions(),
    projectController.projectAnalytics,
  );

router.route('/create-from-search').post(
  // instead of creating new Api end point we can allow user to create project from search
  userAuthAndCheckPermissions(),
  validateMiddleware(projectValidation.createFromSearch),
  projectController.createFromSearch,
);

router
  .route('/:id')
  .get(
    userAuthAndCheckPermissions(),
    validateMiddleware(projectValidation.getProjectById),
    projectController.getProjectById,
  )
  .patch(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.UPDATE),
    validateMiddleware(projectValidation.updateProject()),
    setAuditFields({ mode: AuditMode.UPDATE }),
    projectController.updateProject,
  )
  .delete(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.DELETE),
    validateMiddleware(projectValidation.deleteProjectById),
    projectController.deleteProject,
  );

router
  .route('/:id/amenities')
  .patch(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.UPDATE),
    validateMiddleware(projectValidation.updateProjectAmenities),
    setAuditFields({ mode: AuditMode.UPDATE }),
    projectController.updateProjectAmenities,
  );

router
  .route('/:id/visibility')
  .patch(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.UPDATE),
    validateMiddleware(projectValidation.updateProjectVisibility),
    setAuditFields({ mode: AuditMode.UPDATE }),
    projectController.updateProjectVisibility,
  );

router
  .route('/visibility/bulk-update')
  .patch(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.UPDATE),
    validateMiddleware(projectValidation.updateProjectsPublicVisibility),
    setAuditFields({ mode: AuditMode.UPDATE }),
    projectController.updateProjectsPublicVisibility,
  );

router
  .route('/:projectId/units')
  .get(
    userAuthAndCheckPermissions(),
    validateMiddleware(unitValidation.getUnitsByProjectId),
    unitController.getUnitsByProjectId,
  )
  .post(
    validateMiddleware(unitValidation.createUnit()),
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.CREATE),
    setAuditFields({ mode: AuditMode.CREATE }),
    unitController.createUnit,
  );

router
  .route('/:projectId/units/analytics')
  .get(
    userAuthAndCheckPermissions(),
    unitController.getUnitsByProjectIdAnalytics,
  );

router
  .route('/:projectId/units/download-excel-template')
  .get(userAuthAndCheckPermissions(), unitController.downloadUnitsExcel);

router.route('/:projectId/units/upload-excel').post(
  userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.CREATE),
  validateMiddleware(unitValidation.uploadUnitsExcel),
  upload({
    destination: 'uploads/files',
    fileTypes: [
      'application/vnd.ms-excel', // .xls
      'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', // .xlsx
    ],
    maxFileSize: 10 * 1024 * 1024, // 10MB
    fieldName: 'file',
  }),
  unitController.uploadUnitsExcel,
);

router
  .route('/:projectId/units/:id')
  .get(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.READ),
    validateMiddleware(unitValidation.getUnitById),
    unitController.getUnitById,
  )
  .patch(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.UPDATE),
    validateMiddleware(unitValidation.updateUnit()),
    setAuditFields({ mode: AuditMode.UPDATE }),
    unitController.updateUnit,
  )
  .delete(
    userAuthAndCheckPermissions(MODULE_LIST.PROJECT, ACTIONS.DELETE),
    userAuthAndCheckPermissions(),
    validateMiddleware(unitValidation.deleteUnitById),
    unitController.deleteUnit,
  );

router.use('/:projectId/payment-terms', paymentTermRoutes);
router.use('/:projectId/timelines', timelineRoutes);
router.use('/:projectId/files', fileRoutes);

export default router;
