// Admin · uo-link — the sidecar connection config, the town crier, and the
// staff SSE stream.
//
// Mounted at /api/v1/admin/uo-link by admin/index.js, which already applied
// `noindex, isLoggedIn, staffOnly`. This is where shard integration is
// configured: base/ws URL, bearer token, protocol version and the enabled
// toggle all live in the DB (uoLinkConfig), never in env. The token is
// write-only over this API (SECURITY note in uoLink.controller.js).
//
// /stream is the ADMIN SSE channel — it carries staff audit, cheat detection
// and login attempts on top of the public event kinds. The public/admin
// allowlist split in utils/shardIngest.js is a security boundary; the adminOnly
// gate below is its other half.
//
// The routes keep their `Admin · Shard` swagger tag: retagging is a real
// OpenAPI diff and does not belong in a route-move PR.
//
// Admin-only, and kept as a per-route gate rather than a router-level `use` so
// the middleware chain each route carries is unchanged by the move.

const express = require('express')
const { body, param } = require('express-validator')

const uoLink = require('./uoLink.controller')
const { requireRole } = require('../../../utils/auth')
const validate = require('../../../middleware/validate')

const uoLinkRouter = express.Router()
const adminOnly = requireRole('admin')

uoLinkRouter.get(
  '/config',
  // #swagger.tags = ['Admin · Shard']
  // #swagger.summary = 'Get uo-link config + live status + ingestion stats (admin only)'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.responses[200] = { description: 'Masked config, health and ingestion stats', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[403] = { description: 'Admin role required', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  adminOnly,
  uoLink.getConfig,
)
uoLinkRouter.put(
  '/config',
  // #swagger.tags = ['Admin · Shard']
  // #swagger.summary = 'Save uo-link connection config (admin only)'
  // #swagger.description = 'token is write-only — omit/blank it to keep the existing one. Saving (re)starts the WS ingest client.'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { type: "object", properties: { baseUrl: { type: "string" }, wsUrl: { type: "string" }, token: { type: "string" }, protocol: { type: "integer" }, enabled: { type: "boolean" } } } } } } */
  /* #swagger.responses[200] = { description: 'Updated config + live status', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[400] = { description: 'Validation error, or missing token while enabling', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[403] = { description: 'Admin role required', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  adminOnly,
  body('baseUrl').optional({ values: 'falsy' }).isString().trim().isURL({ require_tld: false, protocols: ['http', 'https'] }),
  body('wsUrl').optional({ values: 'falsy' }).isString().trim().isURL({ require_tld: false, protocols: ['ws', 'wss'] }),
  body('token').optional({ values: 'falsy' }).isString().trim(),
  body('protocol').optional().isInt({ min: 1, max: 99 }),
  body('enabled').optional().isBoolean(),
  validate,
  uoLink.saveConfig,
)
uoLinkRouter.post(
  '/towncrier',
  // #swagger.tags = ['Admin · Shard']
  // #swagger.summary = 'Publish / replace a town-crier message (admin only)'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/TownCrierRequest" } } } } */
  /* #swagger.responses[200] = { description: 'Posted', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[400] = { description: 'Rejected (over caps)', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  adminOnly,
  body('id').isString().trim().isLength({ min: 1, max: 64 }),
  body('lines').isArray({ min: 1, max: 8 }),
  body('lines.*').isString().isLength({ max: 200 }),
  body('durationSec').optional().isInt({ min: 1, max: 86400 }),
  validate,
  uoLink.postTownCrier,
)
uoLinkRouter.delete(
  '/towncrier/:id',
  // #swagger.tags = ['Admin · Shard']
  // #swagger.summary = 'Remove a town-crier message (admin only)'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  // #swagger.parameters['id'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'Town-crier message id.' }
  /* #swagger.responses[200] = { description: 'Removed', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[404] = { description: 'Unknown id', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  adminOnly,
  param('id').isString().trim().isLength({ min: 1, max: 64 }),
  validate,
  uoLink.deleteTownCrier,
)
uoLinkRouter.get(
  '/stream',
  // #swagger.tags = ['Admin · Shard']
  // #swagger.summary = 'Full live shard event stream incl. audit/cheat (SSE, admin only)'
  /* #swagger.responses[200] = { description: 'An SSE stream (Content-Type: text/event-stream).' } */
  adminOnly,
  uoLink.stream,
)

module.exports = uoLinkRouter
