// signaling-server.js
// Minimal Socket.io signaling server for AeThex Connect (Supabase JWT auth)

const http = require('http');
const { Server } = require('socket.io');
const fetch = require('node-fetch');
require('dotenv').config();

const { createClient } = require('@supabase/supabase-js');

const PORT = 3000;
const SUPABASE_URL = process.env.SUPABASE_URL;
const SUPABASE_ANON_KEY = process.env.SUPABASE_ANON_KEY;

// Supabase client for DB operations
const supabase = createClient(SUPABASE_URL, SUPABASE_ANON_KEY);

const server = http.createServer();
const io = new Server(server, {
  cors: { origin: '*' }
});

// Helper: Validate Supabase JWT
async function validateSupabaseJWT(token) {
  // Use Supabase's /user endpoint to validate JWT
  const res = await fetch(`${SUPABASE_URL}/auth/v1/user`, {
    headers: {
      'Authorization': `Bearer ${token}`,
      'apikey': SUPABASE_ANON_KEY
    }
  });
  if (!res.ok) return null;
  return res.json();
}

io.use(async (socket, next) => {
  const token = socket.handshake.auth?.token;
  if (!token) return next(new Error('Authentication required'));
  const user = await validateSupabaseJWT(token);
  if (!user) return next(new Error('Invalid token'));
  socket.user = user;
  next();
});

io.on('connection', (socket) => {
  console.log(`User connected: ${socket.user.email}`);

  // WebRTC signaling events
  socket.on('voice:join', (roomId) => {
    socket.join(`voice:${roomId}`);
    socket.to(`voice:${roomId}`).emit('voice:user-joined', {
      user: socket.user
    });
  });

  socket.on('voice:offer', (roomId, offer) => {
    socket.to(`voice:${roomId}`).emit('voice:offer', {
      from: socket.user,
      offer
    });
  });

  socket.on('voice:answer', (roomId, answer) => {
    socket.to(`voice:${roomId}`).emit('voice:answer', {
      from: socket.user,
      answer
    });
  });

  socket.on('voice:ice-candidate', (roomId, candidate) => {
    socket.to(`voice:${roomId}`).emit('voice:ice-candidate', {
      from: socket.user,
      candidate
    });
  });

  socket.on('voice:leave', (roomId) => {
    socket.leave(`voice:${roomId}`);
    socket.to(`voice:${roomId}`).emit('voice:user-left', {
      user: socket.user
    });
  });

  // Game sync events (example)
  socket.on('game:join', (gameId) => {
    socket.join(`game:${gameId}`);
    socket.to(`game:${gameId}`).emit('game:player-joined', {
      user: socket.user
    });
  });

  socket.on('game:position', (gameId, position) => {
    socket.to(`game:${gameId}`).emit('game:player-position', {
      user: socket.user,
      position
    });
  });

  socket.on('disconnect', () => {
    console.log(`User disconnected: ${socket.user.email}`);
  });

  // ===== Minimal Chat (channels, DMs, presence) =====

  // Join a chat channel
  socket.on('chat:join', async (channelId) => {
    socket.join(`chat:${channelId}`);
    // Mark user as present in channel (optional: store in-memory or in DB)
    socket.to(`chat:${channelId}`).emit('chat:user-joined', {
      user: socket.user,
      channelId
    });
  });

  // Leave a chat channel
  socket.on('chat:leave', (channelId) => {
    socket.leave(`chat:${channelId}`);
    socket.to(`chat:${channelId}`).emit('chat:user-left', {
      user: socket.user,
      channelId
    });
  });

  // Send a chat message
  socket.on('chat:message', async (channelId, text) => {
    const message = {
      user_id: socket.user.id,
      username: socket.user.user_metadata?.username || socket.user.email,
      text,
      channel_id: channelId,
      created_at: new Date().toISOString()
    };
    // Store message in Supabase
    await supabase.from('messages').insert([message]);
    // Broadcast to channel
    io.to(`chat:${channelId}`).emit('chat:message', message);
  });

  // Fetch recent messages for a channel
  socket.on('chat:history', async (channelId, cb) => {
    const { data, error } = await supabase
      .from('messages')
      .select('*')
      .eq('channel_id', channelId)
      .order('created_at', { ascending: false })
      .limit(50);
    if (cb) cb(data || []);
  });
});

server.listen(PORT, () => {
  console.log(`Signaling server running on port ${PORT}`);
});
