import { Router, Request, Response, NextFunction } from 'express';
import { actionItemsService } from './action-items.service';
import {
  createActionItemSchema,
  updateActionItemSchema,
  listActionItemsSchema,
} from './action-items.schemas';
import { validate } from '../../middleware/validate';
import { authenticate } from '../../middleware/auth.middleware';
import { requireRole } from '../../middleware/rbac.middleware';
import { EVENTS_ROLES, hasAnyRole } from '../../utils/roles';
import { AppError } from '../../middleware/error-handler';

const router = Router();

// --- Routes requiring EVENTS_ROLES ---

// List all action items
router.get('/', authenticate, requireRole(...EVENTS_ROLES), validate(listActionItemsSchema, 'query'), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const result = await actionItemsService.findAll(req.query as any);
    res.json(result);
  } catch (err) { next(err); }
});

// Current user's action items (authenticate only)
router.get('/mine', authenticate, async (req: Request, res: Response, next: NextFunction) => {
  try {
    const status = req.query.status as string | undefined;
    const items = await actionItemsService.findByUser(req.user!.id, status);
    res.json(items);
  } catch (err) { next(err); }
});

// Overdue items
router.get('/overdue', authenticate, requireRole(...EVENTS_ROLES), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const items = await actionItemsService.getOverdue();
    res.json(items);
  } catch (err) { next(err); }
});

// Get action item detail
router.get('/:id', authenticate, async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const item = await actionItemsService.findById(id);

    const isAdmin = hasAnyRole(req.user!, EVENTS_ROLES);
    const isAssignee = item.assigneeUserId === req.user!.id;
    const isCreator = item.createdByUserId === req.user!.id;
    if (!isAdmin && !isAssignee && !isCreator) {
      throw new AppError(403, 'Insufficient permissions', 'FORBIDDEN');
    }

    res.json(item);
  } catch (err) { next(err); }
});

// Create action item
router.post('/', authenticate, requireRole(...EVENTS_ROLES), validate(createActionItemSchema), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const item = await actionItemsService.create(req.body, req.user!.id);
    res.status(201).json(item);
  } catch (err) { next(err); }
});

// Update action item — admins, assignees, or creators can update
router.put('/:id', authenticate, validate(updateActionItemSchema), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    const existing = await actionItemsService.findById(id);

    const isAdmin = hasAnyRole(req.user!, EVENTS_ROLES);
    const isAssignee = existing.assigneeUserId === req.user!.id;
    const isCreator = existing.createdByUserId === req.user!.id;
    if (!isAdmin && !isAssignee && !isCreator) {
      throw new AppError(403, 'Insufficient permissions', 'FORBIDDEN');
    }

    const item = await actionItemsService.update(id, req.body);
    res.json(item);
  } catch (err) { next(err); }
});

// Delete action item
router.delete('/:id', authenticate, requireRole(...EVENTS_ROLES), async (req: Request, res: Response, next: NextFunction) => {
  try {
    const id = req.params.id as string;
    await actionItemsService.delete(id);
    res.json({ message: 'Action item deleted' });
  } catch (err) { next(err); }
});

export { router as actionItemsRouter };
