import { Router, Request, Response, NextFunction } from 'express';
import { representativesService } from './representatives.service';
import { listRepresentativesSchema } from './representatives.schemas';
import { postalCodeParamSchema, postalCodeQuerySchema } from '../postal-codes/postal-codes.schemas';
import { validate } from '../../../middleware/validate';
import { authenticate } from '../../../middleware/auth.middleware';
import { requireRole } from '../../../middleware/rbac.middleware';
import { INFLUENCE_ROLES } from '../../../utils/roles';

const router = Router();

// =============================================
// PUBLIC ROUTES (no auth required)
// =============================================

// GET /api/representatives/by-postal/:postalCode — cache-first lookup
router.get(
  '/by-postal/:postalCode',
  validate(postalCodeParamSchema, 'params'),
  validate(postalCodeQuerySchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const code = req.params.postalCode as string;
      const refresh = req.query.refresh === 'true';
      const result = await representativesService.lookupByPostalCode(code, refresh);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/representatives/test-connection — Represent API health check
router.get(
  '/test-connection',
  async (_req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await representativesService.testApiConnection();
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// =============================================
// ADMIN ROUTES (auth + role required)
// =============================================

router.use(authenticate);
router.use(requireRole(...INFLUENCE_ROLES));

// GET /api/representatives/cache-stats — cache statistics
router.get(
  '/cache-stats',
  async (_req: Request, res: Response, next: NextFunction) => {
    try {
      const stats = await representativesService.getCacheStats();
      res.json(stats);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/representatives — list all cached reps (paginated)
router.get(
  '/',
  validate(listRepresentativesSchema, 'query'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const result = await representativesService.findAll(req.query as any);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// GET /api/representatives/:id — single cached rep
router.get(
  '/:id',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      const rep = await representativesService.findById(id);
      res.json(rep);
    } catch (err) {
      next(err);
    }
  }
);

// DELETE /api/representatives/by-postal/:postalCode — clear cache for postal code
router.delete(
  '/by-postal/:postalCode',
  validate(postalCodeParamSchema, 'params'),
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const code = req.params.postalCode as string;
      const result = await representativesService.clearByPostalCode(code);
      res.json(result);
    } catch (err) {
      next(err);
    }
  }
);

// DELETE /api/representatives/:id — delete single cached rep
router.delete(
  '/:id',
  async (req: Request, res: Response, next: NextFunction) => {
    try {
      const id = req.params.id as string;
      await representativesService.deleteById(id);
      res.status(204).send();
    } catch (err) {
      next(err);
    }
  }
);

export { router as representativesRouter };
