import express from 'express';
import * as companyController from '../controllers/company.controller.js';
import * as companyNoteController from '../controllers/company-note.controller.js';
import * as companyReminderController from '../controllers/company-reminder.controller.js';
import * as companyTeamController from '../controllers/company-team.controller.js';
import * as personalContactController from '../controllers/personal-contact.controller.js';
import * as companyDocumentController from '../controllers/company-document.controller.js';
import { authenticate } from '../middlewares/auth/authMiddleware.js';
import { requireAdmin } from '../middlewares/auth/roleMiddleware.js';
import { checkCompanyAccess } from '../middlewares/auth/resourceAccessMiddleware.js';
import { validateBody, validateParams } from '../middlewares/security/validateInput.js';
import { createCompanySchema, updateCompanySchema, createCompanyReminderSchema, updateCompanyReminderSchema } from '../validators/crm.validators.js';
import { z } from 'zod';
import { createUpload } from '../config/upload.js';

const upload = createUpload({ maxSizeMB: 50 });

const router = express.Router();

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

// Reminder summaries (must be before :companyId routes)
router.get('/reminders/summary', companyReminderController.getReminderSummary);
router.get('/reminders/counts', companyReminderController.getReminderCountsByCompany);
router.get('/reminders/upcoming', companyReminderController.getUpcomingReminders);

// Company unread email summary
router.get('/email-unread', companyController.getCompanyUnreadCounts);

// Company email threads
router.get(
  '/:companyId/email-threads',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyController.getCompanyEmailThreads
);

/**
 * Company management
 */

// Get all companies
router.get('/', companyController.getAllCompanies);

// Get company by ID
router.get(
  '/:companyId',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyController.getCompanyById
);

// Create new company (any authenticated user)
router.post(
  '/',
  validateBody(createCompanySchema),
  companyController.createCompany
);

// Update company (admin only)
router.patch(
  '/:companyId',
  requireAdmin,
  validateParams(z.object({ companyId: z.string().uuid() })),
  validateBody(updateCompanySchema),
  companyController.updateCompany
);

// Delete company (admin only)
router.delete(
  '/:companyId',
  requireAdmin,
  validateParams(z.object({ companyId: z.string().uuid() })),
  companyController.deleteCompany
);

// Company Notes (nested resources)
router.get(
  '/:companyId/notes',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyNoteController.getCompanyNotes
);

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

router.patch(
  '/:companyId/notes/:noteId',
  requireAdmin,
  validateParams(z.object({
    companyId: 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())),
  })),
  companyNoteController.updateCompanyNote
);

router.delete(
  '/:companyId/notes/:noteId',
  requireAdmin,
  validateParams(z.object({
    companyId: z.string().uuid(),
    noteId: z.string().uuid()
  })),
  companyNoteController.deleteCompanyNote
);

// Company reminders
router.get(
  '/:companyId/reminders',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyReminderController.getCompanyReminders
);

router.post(
  '/:companyId/reminders',
  requireAdmin,
  validateParams(z.object({ companyId: z.string().uuid() })),
  validateBody(createCompanyReminderSchema),
  companyReminderController.createCompanyReminder
);

router.patch(
  '/:companyId/reminders/:reminderId',
  requireAdmin,
  validateParams(z.object({
    companyId: z.string().uuid(),
    reminderId: z.string().uuid()
  })),
  validateBody(updateCompanyReminderSchema),
  companyReminderController.updateCompanyReminder
);

router.delete(
  '/:companyId/reminders/:reminderId',
  requireAdmin,
  validateParams(z.object({
    companyId: z.string().uuid(),
    reminderId: z.string().uuid()
  })),
  companyReminderController.deleteCompanyReminder
);

// Company Users (Team Management)
router.get(
  '/:companyId/users',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyTeamController.getCompanyUsers
);

router.post(
  '/:companyId/users',
  requireAdmin,
  validateParams(z.object({ companyId: z.string().uuid() })),
  validateBody(z.object({
    userId: z.string().uuid(),
    role: z.string().optional(),
  })),
  companyTeamController.assignUserToCompany
);

router.patch(
  '/:companyId/users/:userId',
  requireAdmin,
  validateParams(z.object({
    companyId: z.string().uuid(),
    userId: z.string().uuid()
  })),
  validateBody(z.object({
    role: z.string().optional(),
  })),
  companyTeamController.updateUserRoleOnCompany
);

router.delete(
  '/:companyId/users/:userId',
  requireAdmin,
  validateParams(z.object({
    companyId: z.string().uuid(),
    userId: z.string().uuid()
  })),
  companyTeamController.removeUserFromCompany
);

// Company Contacts (Personal contacts linked to company)
router.get(
  '/:companyId/contacts',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  personalContactController.getContactsByCompany
);

// Company Documents
router.get(
  '/:companyId/documents',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  companyDocumentController.getDocuments
);

router.post(
  '/:companyId/documents',
  validateParams(z.object({ companyId: z.string().uuid() })),
  checkCompanyAccess,
  upload.single('file'),
  companyDocumentController.uploadDocument
);

router.get(
  '/:companyId/documents/:docId/download',
  validateParams(z.object({
    companyId: z.string().uuid(),
    docId: z.string().uuid()
  })),
  checkCompanyAccess,
  companyDocumentController.downloadDocument
);

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

export default router;
