// ── config/init ───────────────────────────────
const config = require('config');
const express = require('express');
const axios = require('axios');
const http = require('http');

const URL_BASE = config.get('url_base');
const API_PORT = config.get('api_port');
const SOCKET_PORT = config.get('socket_port');
const SOCKET_VERSION = '1000';
const SOCKET_AUTH = '3calsDCnVxcpoX3caAkkcp';

// ── SocketServer class ────────────────────────
class SocketServer {
    constructor(io, version = '1000') {
        this.io = io;
        this.version = version;
        this.setupListeners();
    }

    setupListeners() {
        this.io.on("connection", socket => {
            socket.uniqueId = Math.random().toString(36).split(".")[1];

            socket.on('disconnect', reason => {
                const uid = socket.userid || 'unknown user';
                logLine(socket.uniqueId, ':', uid, 'disconnected:', reason);
            });

            socket.emit("chat_version", parseInt(this.version));

            socket.on('register', userid => {
                socket.userid = userid;
                socket.join('user_' + userid);
                logLine(socket.uniqueId, ':', 'user connected:', userid);
            });
        });
    }
}

// ── Logging Utils ─────────────────────────────
function logLine(...args) {
    args.unshift(formatDate(new Date()) + ' ');
    console.log(...args);
}
const pad2 = n => n.toString().padStart(2, '0');
function formatDate(d) {
    return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())} ${pad2(d.getHours())}:${pad2(d.getMinutes())}:${pad2(d.getSeconds())}`;
}

// ── API Server Setup ──────────────────────────
const app = express();
app.use(express.json());

app.post('/event', (req, res) => {
    if (!apiAuth(req)) {
        return res.send(apiResponse(false, { message: 'failed or missing auth' }));
    }

    const { event, target, payload } = req.body;
    const [scope] = event.split('_');
    const room = (scope === 'pub' ? 'pub_' : 'user_') + target;

    logLine('event:', JSON.stringify(req.body, null, 2));
    io.to(room).emit(event, payload);

    res.send(apiResponse(true, { message: 'processed' }));
});

function apiAuth(req) {
    return req.headers.xauth === SOCKET_AUTH;
}

function apiResponse(success, data) {
    return { success, data };
}

// ── Startup ───────────────────────────────────
const io = require("socket.io")(SOCKET_PORT);
new SocketServer(io);
app.listen(API_PORT, () => {
    logLine(`Socket and API is now listening on port ${API_PORT}`);
});
