import express from 'express';
import * as projectController from '../controllers/project.controller.js';
import * as projectDocumentController from '../controllers/project-document.controller.js';
import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
import { checkProjectAccess } from '../middlewares/auth/resourceAccessMiddleware.js';
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
import { createProjectSchema, updateProjectSchema } from '../validators/crm.validators.js';
import { z } from 'zod';
import { createUpload, ALLOWED_FILE_TYPES } from '../config/upload.js';

const upload = createUpload({
  maxSizeMB: 20,
  allowedTypes: ALLOWED_FILE_TYPES,
  errorMessage: 'Nepovolený typ súboru. Povolené: PDF, Word, Excel, PowerPoint, obrázky, CSV, TXT.',
});

const router = express.Router();

// All project routes require authentication
router.use(authenticate);

/**
 * Project management
 */

// Get all projects
router.get('/', projectController.getAllProjects);

// Get project by ID
router.get(
  '/:projectId',
  validateParams(z.object({ projectId: z.string().uuid() })),
  checkProjectAccess,
  projectController.getProjectById
);

// Create new project (any authenticated user)
router.post(
  '/',
  validateBody(createProjectSchema),
  projectController.createProject
);

// Update project (team members and admins)
router.patch(
  '/:projectId',
  checkProjectAccess,
  validateParams(z.object({ projectId: z.string().uuid() })),
  validateBody(updateProjectSchema),
  projectController.updateProject
);

// Delete project (admin only)
router.delete(
  '/:projectId',
  requireAdmin,
  validateParams(z.object({ projectId: z.string().uuid() })),
  projectController.deleteProject
);

// Project Notes (nested resources)
router.get(
  '/:projectId/notes',
  validateParams(z.object({ projectId: z.string().uuid() })),
  checkProjectAccess,
  projectController.getProjectNotes
);

router.post(
  '/:projectId/notes',
  requireAdmin,
  validateParams(z.object({ projectId: z.string().uuid() })),
  validateBody(z.object({
    content: z.string().min(1),
    dueDate: z.string().optional().or(z.literal('')),
  })),
  projectController.addProjectNote
);

router.patch(
  '/:projectId/notes/:noteId',
  requireAdmin,
  validateParams(z.object({
    projectId: z.string().uuid(),
    noteId: z.string().uuid()
  })),
  validateBody(z.object({
    content: z.string().min(1).optional(),
    dueDate: z.string().optional().or(z.literal('').or(z.null())),
  })),
  projectController.updateProjectNote
);

router.delete(
  '/:projectId/notes/:noteId',
  requireAdmin,
  validateParams(z.object({
    projectId: z.string().uuid(),
    noteId: z.string().uuid()
  })),
  projectController.deleteProjectNote
);

// Project Users (team members)
router.get(
  '/:projectId/users',
  validateParams(z.object({ projectId: z.string().uuid() })),
  checkProjectAccess,
  projectController.getProjectUsers
);

router.post(
  '/:projectId/users',
  requireAdmin,
  validateParams(z.object({ projectId: z.string().uuid() })),
  validateBody(z.object({
    userId: z.string().uuid('Neplatný formát user ID'),
    role: z.string().max(50).optional().or(z.literal('')),
  })),
  projectController.assignUserToProject
);

router.patch(
  '/:projectId/users/:userId',
  requireAdmin,
  validateParams(z.object({
    projectId: z.string().uuid(),
    userId: z.string().uuid()
  })),
  validateBody(z.object({
    role: z.string().max(50).optional().or(z.literal('').or(z.null())),
  })),
  projectController.updateUserRoleOnProject
);

router.delete(
  '/:projectId/users/:userId',
  requireAdmin,
  validateParams(z.object({
    projectId: z.string().uuid(),
    userId: z.string().uuid()
  })),
  projectController.removeUserFromProject
);

// Project Documents
router.get(
  '/:projectId/documents',
  validateParams(z.object({ projectId: z.string().uuid() })),
  checkProjectAccess,
  projectDocumentController.getDocuments
);

router.post(
  '/:projectId/documents',
  validateParams(z.object({ projectId: z.string().uuid() })),
  checkProjectAccess,
  upload.single('file'),
  projectDocumentController.uploadDocument
);

router.get(
  '/:projectId/documents/:docId/download',
  validateParams(z.object({
    projectId: z.string().uuid(),
    docId: z.string().uuid()
  })),
  checkProjectAccess,
  projectDocumentController.downloadDocument
);

router.delete(
  '/:projectId/documents/:docId',
  requireAdmin,
  validateParams(z.object({
    projectId: z.string().uuid(),
    docId: z.string().uuid()
  })),
  projectDocumentController.deleteDocument
);

export default router;
