"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.responsesAdminRouter = exports.responsesPublicRouter = exports.responseCampaignPublicRouter = void 0;
const express_1 = require("express");
const responses_service_1 = require("./responses.service");
const responses_schemas_1 = require("./responses.schemas");
const validate_1 = require("../../../middleware/validate");
const auth_middleware_1 = require("../../../middleware/auth.middleware");
const auth_middleware_2 = require("../../../middleware/auth.middleware");
const rbac_middleware_1 = require("../../../middleware/rbac.middleware");
const rate_limit_1 = require("../../../middleware/rate-limit");
const roles_1 = require("../../../utils/roles");
// --- Campaign-scoped public routes (mount at /api/campaigns) ---
const campaignPublicRouter = (0, express_1.Router)();
exports.responseCampaignPublicRouter = campaignPublicRouter;
// GET /api/campaigns/:slug/responses
campaignPublicRouter.get('/:slug/responses', (0, validate_1.validate)(responses_schemas_1.listPublicResponsesSchema, 'query'), async (req, res, next) => {
    try {
        const slug = req.params.slug;
        const result = await responses_service_1.responsesService.listApproved(slug, req.query);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// GET /api/campaigns/:slug/response-stats
campaignPublicRouter.get('/:slug/response-stats', async (req, res, next) => {
    try {
        const slug = req.params.slug;
        const stats = await responses_service_1.responsesService.getStats(slug);
        res.json(stats);
    }
    catch (err) {
        next(err);
    }
});
// POST /api/campaigns/:slug/responses
campaignPublicRouter.post('/:slug/responses', rate_limit_1.responseRateLimit, (0, validate_1.validate)(responses_schemas_1.submitResponseSchema), async (req, res, next) => {
    try {
        const slug = req.params.slug;
        const senderIp = req.ip || req.socket.remoteAddress;
        const result = await responses_service_1.responsesService.submitResponse(slug, req.body, senderIp);
        res.status(201).json(result);
    }
    catch (err) {
        next(err);
    }
});
// --- Response-scoped public routes (mount at /api/responses) ---
const responsesPublicRouter = (0, express_1.Router)();
exports.responsesPublicRouter = responsesPublicRouter;
// POST /api/responses/:id/upvote
responsesPublicRouter.post('/:id/upvote', auth_middleware_2.optionalAuth, async (req, res, next) => {
    try {
        const id = req.params.id;
        const userIp = req.ip || req.socket.remoteAddress;
        const userId = req.user?.id;
        const result = await responses_service_1.responsesService.upvote(id, userIp, userId);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// DELETE /api/responses/:id/upvote
responsesPublicRouter.delete('/:id/upvote', auth_middleware_2.optionalAuth, async (req, res, next) => {
    try {
        const id = req.params.id;
        const userIp = req.ip || req.socket.remoteAddress;
        const userId = req.user?.id;
        const result = await responses_service_1.responsesService.removeUpvote(id, userIp, userId);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// GET /api/responses/:id/verify/:token — returns HTML page
responsesPublicRouter.get('/:id/verify/:token', async (req, res, next) => {
    try {
        const id = req.params.id;
        const token = req.params.token;
        const result = await responses_service_1.responsesService.verify(id, token);
        const html = result.success
            ? buildResultPage('Response Verified', `Thank you for verifying this response for the "${result.campaignTitle}" campaign. The response has been approved and will now appear on the public response wall.`, '#16a34a')
            : buildResultPage('Verification Failed', result.reason || 'Unable to verify this response.', '#dc2626');
        res.type('html').send(html);
    }
    catch (err) {
        next(err);
    }
});
// GET /api/responses/:id/report/:token — returns HTML page
responsesPublicRouter.get('/:id/report/:token', async (req, res, next) => {
    try {
        const id = req.params.id;
        const token = req.params.token;
        const result = await responses_service_1.responsesService.report(id, token);
        const html = result.success
            ? buildResultPage('Response Reported', `This response for the "${result.campaignTitle}" campaign has been flagged as invalid and removed from the public response wall. Thank you for letting us know.`, '#dc2626')
            : buildResultPage('Report Failed', result.reason || 'Unable to process this report.', '#dc2626');
        res.type('html').send(html);
    }
    catch (err) {
        next(err);
    }
});
// --- Admin routes (mount at /api/responses) ---
const responsesAdminRouter = (0, express_1.Router)();
exports.responsesAdminRouter = responsesAdminRouter;
responsesAdminRouter.use(auth_middleware_1.authenticate);
responsesAdminRouter.use((0, rbac_middleware_1.requireRole)(...roles_1.INFLUENCE_ROLES));
// GET /api/responses
responsesAdminRouter.get('/', (0, validate_1.validate)(responses_schemas_1.listAdminResponsesSchema, 'query'), async (req, res, next) => {
    try {
        const result = await responses_service_1.responsesService.findAll(req.query);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// PATCH /api/responses/:id/status
responsesAdminRouter.patch('/:id/status', (0, validate_1.validate)(responses_schemas_1.updateResponseStatusSchema), async (req, res, next) => {
    try {
        const id = req.params.id;
        const result = await responses_service_1.responsesService.updateStatus(id, req.body);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// POST /api/responses/:id/resend-verification
responsesAdminRouter.post('/:id/resend-verification', async (req, res, next) => {
    try {
        const id = req.params.id;
        const result = await responses_service_1.responsesService.resendVerification(id);
        res.json(result);
    }
    catch (err) {
        next(err);
    }
});
// DELETE /api/responses/:id
responsesAdminRouter.delete('/:id', async (req, res, next) => {
    try {
        const id = req.params.id;
        await responses_service_1.responsesService.deleteResponse(id);
        res.status(204).send();
    }
    catch (err) {
        next(err);
    }
});
// --- HTML page builder for verify/report endpoints ---
function escapeHtml(unsafe) {
    return unsafe
        .replace(/&/g, '&amp;')
        .replace(/</g, '&lt;')
        .replace(/>/g, '&gt;')
        .replace(/"/g, '&quot;')
        .replace(/'/g, '&#x27;');
}
function buildResultPage(title, message, accentColor) {
    const escapedTitle = escapeHtml(title);
    const escapedMessage = escapeHtml(message);
    return `<!DOCTYPE html>
<html>
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>${escapedTitle} - Changemaker Lite</title>
  <style>
    body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; margin: 0; padding: 40px 20px; background: #f8fafc; color: #334155; }
    .container { max-width: 500px; margin: 0 auto; text-align: center; }
    .card { background: white; border-radius: 12px; padding: 40px; box-shadow: 0 1px 3px rgba(0,0,0,0.1); }
    .icon { font-size: 48px; margin-bottom: 16px; }
    h1 { color: ${accentColor}; font-size: 24px; margin: 0 0 16px; }
    p { font-size: 16px; line-height: 1.6; color: #64748b; margin: 0; }
    .brand { margin-top: 32px; font-size: 14px; color: #94a3b8; }
    .brand strong { color: #2563eb; }
  </style>
</head>
<body>
  <div class="container">
    <div class="card">
      <div class="icon">${accentColor === '#16a34a' ? '&#10003;' : '&#10007;'}</div>
      <h1>${escapedTitle}</h1>
      <p>${escapedMessage}</p>
    </div>
    <div class="brand">Powered by <strong>Changemaker Lite</strong></div>
  </div>
</body>
</html>`;
}
//# sourceMappingURL=responses.routes.js.map