// Player · Shard — game-account linking and the caller's own roster / vendors /
// characters / sales / houses, ownership-checked against the local link mirror.
//
// Mounted at /api/v1/player/shard by player/index.js, which already applied
// `noindex, requireAuth`. No extra gate: every handler is self-scoped to
// req.user.id.
//
// These are the *same* handlers (player/shard.controller) that admin/shard.router.js
// serves under /admin/shard for the seven self-service routes — staff are a
// superset of players, and the controller keys off req.user.id either way. Two
// URL surfaces, one implementation.

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

const shard = require('./shard.controller')
const validate = require('../../../middleware/validate')
const { accountChangeLimiter } = require('../../../middleware/rateLimit')

const shardRouter = express.Router()

// Link an in-game account with a one-time code from [link, then read the
// account's roster / vendors (ownership-checked against the local link mirror).
const ACCOUNT_RE = /^[A-Za-z0-9_.-]{1,120}$/

shardRouter.post(
  '/link',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Link an in-game account with a one-time code'
  // #swagger.description = 'The player runs [link in game to get a code, then submits it here. The server confirms it with the sidecar and mirrors the link.'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { $ref: "#/components/schemas/ShardLinkRequest" } } } } */
  /* #swagger.responses[200] = { description: 'Linked', content: { "application/json": { schema: { $ref: "#/components/schemas/ShardLinkResult" } } } } */
  /* #swagger.responses[400] = { description: 'Unknown or expired code', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable — retry', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  body('code').isString().trim().isLength({ min: 4, max: 32 }),
  validate,
  shard.link,
)
shardRouter.post(
  '/account',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Create a game account (hybrid signup) and link it to the caller'
  // #swagger.description = 'Provisions a new game account with its own username + password and auto-links it to the signed-in website user. Available only when game_account_signup is enabled and the shard accepts website signups. The password is hashed on the shard and never stored or logged by the site.'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.requestBody = { required: true, content: { "application/json": { schema: { type: "object", required: ["account","password"], properties: { account: { type: "string" }, password: { type: "string" } } } } } */
  /* #swagger.responses[201] = { description: 'Account created and linked', content: { "application/json": { schema: { type: "object", properties: { account: { type: "string" }, linked: { type: "boolean" } } } } } } */
  /* #swagger.responses[400] = { description: 'Validation error or rejected name/password', content: { "application/json": { schema: { $ref: "#/components/schemas/ValidationError" } } } } */
  /* #swagger.responses[403] = { description: 'Game-account signup unavailable (site or shard)', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[409] = { description: 'Account name already taken', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[429] = { description: 'Per-IP account cap reached', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable — retry', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  accountChangeLimiter,
  body('account').matches(/^[A-Za-z0-9][A-Za-z0-9_.-]{2,29}$/),
  body('password').isString().isLength({ min: 8, max: 64 }),
  validate,
  shard.createGameAccount,
)
shardRouter.get(
  '/accounts',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'List the caller’s linked game accounts'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.responses[200] = { description: 'Linked accounts', content: { "application/json": { schema: { type: "array", items: { $ref: "#/components/schemas/ShardLink" } } } } } */
  shard.listAccounts,
)
shardRouter.get(
  '/roster/:account',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Character roster for a linked account'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  // #swagger.parameters['account'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'A game account linked to the caller.' }
  /* #swagger.responses[200] = { description: 'Account roster', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[403] = { description: 'Account not linked to the caller', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable — retry', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  param('account').matches(ACCOUNT_RE),
  validate,
  shard.roster,
)
shardRouter.get(
  '/vendors/:account',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Player vendors for a linked account'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  // #swagger.parameters['account'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'A game account linked to the caller.' }
  /* #swagger.responses[200] = { description: 'Vendor snapshot', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[403] = { description: 'Account not linked to the caller', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable — retry', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  param('account').matches(ACCOUNT_RE),
  validate,
  shard.vendors,
)
shardRouter.get(
  '/char/:serial',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Character sheet — only for a character on the caller’s linked account'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  // #swagger.parameters['serial'] = { in: 'path', required: true, schema: { type: 'string' }, description: 'Mobile serial, e.g. 0x24C.' }
  /* #swagger.responses[200] = { description: 'Character profile', content: { "application/json": { schema: { type: "object", additionalProperties: true } } } } */
  /* #swagger.responses[403] = { description: 'Character not on an account linked to the caller', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  /* #swagger.responses[503] = { description: 'Shard unavailable — retry', content: { "application/json": { schema: { $ref: "#/components/schemas/Error" } } } } */
  param('serial').matches(/^0x[0-9a-fA-F]+$/),
  validate,
  shard.getChar,
)
shardRouter.get(
  '/sales',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'Recent player-vendor sales for the caller’s linked accounts'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.responses[200] = { description: 'Vendor sales', content: { "application/json": { schema: { type: "array", items: { $ref: "#/components/schemas/ShardVendorSale" } } } } } */
  shard.getSales,
)
shardRouter.get(
  '/houses',
  // #swagger.tags = ['Player · Shard']
  // #swagger.summary = 'The caller’s own houses (home status)'
  // #swagger.description = 'Houses owned by the caller’s linked accounts, with decay/IDOC status. Only the caller’s own houses — never anyone else’s.'
  // #swagger.security = [{ "cookieAuth": [] }, { "bearerAuth": [] }]
  /* #swagger.responses[200] = { description: 'The caller’s houses', content: { "application/json": { schema: { type: "array", items: { $ref: "#/components/schemas/ShardHouse" } } } } } */
  shard.getHouses,
)

module.exports = shardRouter
