import { Router } from 'express';
import * as projectController from '../controllers/project.controller.js';
import validate from '../middlewares/validate.js';
import verifyFirebaseToken from '../middlewares/verifyFirebaseToken.js';
import authorize from '../middlewares/authorize.js';
import methodNotAllowed from '../middlewares/methodNotAllowed.js';
import { createUploader } from '../middlewares/upload.js';
import { decodeId } from '../utils/idCodec.js';
import { errorResponse } from '../utils/response.js';
import { createProjectSchema, updateProjectSchema, addTeamMemberSchema } from '../validators/project.validator.js';

const router = Router();
const uploadProjectDocument = createUploader('projects');

// Any authenticated user can read (most roles need to see project info, per
// the Planning Module doc's "Other teams — consume the information"); write
// access follows "Project Admin / Planning Team" from the same doc.
const canWrite = authorize('admin', 'organization-admin', 'planning-manager');
const canDelete = authorize('admin', 'organization-admin');
const canManageTeamAndDocs = authorize('admin', 'organization-admin', 'planning-manager', 'project-manager');
// Only a project-manager (or admin) reviews/approves, per the doc's "Project
// Manager — reviews and approves".
const canApprove = authorize('admin', 'project-manager');

router.use(verifyFirebaseToken);

router.param('id', (req, res, next, value: string) => {
  const decoded = decodeId(value);
  if (decoded === null) return void errorResponse(res, 'Invalid id', 400);
  req.params.id = String(decoded);
  next();
});

router.param('memberId', (req, res, next, value: string) => {
  const decoded = decodeId(value);
  if (decoded === null) return void errorResponse(res, 'Invalid id', 400);
  req.params.memberId = String(decoded);
  next();
});

router.param('documentId', (req, res, next, value: string) => {
  const decoded = decodeId(value);
  if (decoded === null) return void errorResponse(res, 'Invalid id', 400);
  req.params.documentId = String(decoded);
  next();
});

router.get('/', projectController.getProjects);
router.post('/', canWrite, validate(createProjectSchema), projectController.createProject);
router.all('/', methodNotAllowed('GET', 'POST'));

router.get('/:id', projectController.getProject);
router.patch('/:id', canWrite, validate(updateProjectSchema), projectController.updateProject);
router.delete('/:id', canDelete, projectController.deleteProject);
router.all('/:id', methodNotAllowed('GET', 'PATCH', 'DELETE'));

router.post('/:id/submit', canWrite, projectController.submitProject);
router.all('/:id/submit', methodNotAllowed('POST'));

router.post('/:id/approve', canApprove, projectController.approveProject);
router.all('/:id/approve', methodNotAllowed('POST'));

router.get('/:id/activity', projectController.getActivityLog);
router.all('/:id/activity', methodNotAllowed('GET'));

router.get('/:id/team', projectController.getTeamMembers);
router.post('/:id/team', canManageTeamAndDocs, validate(addTeamMemberSchema), projectController.addTeamMember);
router.all('/:id/team', methodNotAllowed('GET', 'POST'));

router.delete('/:id/team/:memberId', canManageTeamAndDocs, projectController.removeTeamMember);
router.all('/:id/team/:memberId', methodNotAllowed('DELETE'));

router.get('/:id/documents', projectController.getDocuments);
router.post('/:id/documents', canManageTeamAndDocs, uploadProjectDocument.single('file'), projectController.uploadDocument);
router.all('/:id/documents', methodNotAllowed('GET', 'POST'));

router.get('/:id/documents/:documentId/download', projectController.downloadDocument);
router.all('/:id/documents/:documentId/download', methodNotAllowed('GET'));

router.delete('/:id/documents/:documentId', canManageTeamAndDocs, projectController.deleteDocument);
router.all('/:id/documents/:documentId', methodNotAllowed('DELETE'));

export default router;
