const cors = require('cors');
const { Server, matchMaker } = require('@colyseus/core');
const { WebSocketTransport } = require('@colyseus/ws-transport');
const { ArenaRoom } = require('./rooms/ArenaRoom');
const Stats = require('./stats/StatsManager');
const Chat = require('./chat/ChatManager');
const { z } = require('zod');

const PORT = process.env.PORT || 2567;

const statsUpdateSchema = z.object({
  name: z.string().min(1).max(32),
  stats: z.object({
    totalDistance:    z.number().optional(),
    totalJumps:       z.number().optional(),
    maxSpeed:         z.number().optional(),
    bestRaceTime:     z.number().optional(),
    racesPlayed:      z.number().optional(),
    qualifications:   z.number().optional(),
    eliminations:     z.number().optional(),
    checkpointsTotal: z.number().optional(),
    bumpsGiven:       z.number().optional(),
    totalPlaytime:    z.number().optional(),
  }),
});

const chatSendSchema = z.object({
  name: z.string().min(1).max(32),
  text: z.string().min(1).max(200),
});

let _gameServer;

const gameServer = new Server({
  transport: new WebSocketTransport(),
  express: (app) => {
    app.use(cors());
    app.use(require('express').json());

    app.get('/health', (_req, res) => {
      res.json({ service: 'game', status: 'ok', timestamp: new Date().toISOString() });
    });

    app.get('/', (_req, res) => res.send('🎮 Game server running'));

    // ── Stats ────────────────────────────────────────────────────────────
    app.get('/stats', (_req, res) => {
      res.json(Stats.getAll());
    });

    app.get('/stats/leaderboard/:key', (req, res) => {
      const board = Stats.getLeaderboard(req.params.key);
      if (!board) return res.status(400).json({ error: 'invalid key' });
      res.json(board);
    });

    app.post('/stats/update', (req, res) => {
      const parsed = statsUpdateSchema.safeParse(req.body);
      if (!parsed.success) {
        console.warn('[Stats] Bad update request:', JSON.stringify(parsed.error.issues));
        return res.status(400).json({ error: parsed.error.issues });
      }
      const ok = Stats.update(parsed.data.name, parsed.data.stats);
      console.log(`[Stats] Update for "${parsed.data.name}": ok=${ok}`, JSON.stringify(parsed.data.stats));
      res.json({ ok });
    });

    // ── Rooms ────────────────────────────────────────────────────────────
    app.get('/rooms', async (_req, res) => {
      try {
        const rooms = await matchMaker.query({ name: 'arena' });
        res.json(rooms.map(r => ({
          roomId:     r.roomId,
          clients:    r.clients,
          maxClients: r.maxClients,
          metadata:   r.metadata || {},
        })));
      } catch (_) {
        res.json([]);
      }
    });

    // ── Chat ─────────────────────────────────────────────────────────────
    app.get('/chat/history', (req, res) => {
      res.json(Chat.getHistory(req.query.since));
    });

    app.post('/chat/send', (req, res) => {
      const parsed = chatSendSchema.safeParse(req.body);
      if (!parsed.success) return res.status(400).json({ error: parsed.error.issues });
      const msg = Chat.push(parsed.data.name, parsed.data.text);
      if (!msg) return res.status(429).json({ error: 'empty or invalid message' });

      // Broadcast to all active Colyseus rooms
      if (_gameServer) {
        try {
          const rooms = _gameServer.matchMaker?.rooms;
          if (rooms) {
            for (const room of rooms.values()) {
              room.broadcast('chat', msg);
            }
          }
        } catch (_) {}
      }

      res.json(msg);
    });
  },
});

_gameServer = gameServer;

gameServer.define('arena', ArenaRoom);
console.log('✅ ArenaRoom registered');

gameServer.listen(PORT).then(() => {
  console.log(`🎮 Game server running on ws://localhost:${PORT}`);
});
