import { Router } from 'express';
import { randomBytes } from 'node:crypto';
import { env } from '../../config/env.js';
import { buildDiscordAuthorizeUrl, exchangeCode, fetchDiscordUser } from '../../lib/discord-api.js';
import { verifyCsrf } from '../middleware/auth.js';

export const authRouter = Router();

authRouter.get('/login', (req, res) => {
  if (req.session.discord) return res.redirect(`${env.BASE_PATH}/dashboard`);
  res.render('login', { basePath: env.BASE_PATH, publicUrl: env.PUBLIC_URL });
});

authRouter.get('/auth/discord', (req, res) => {
  const state = randomBytes(24).toString('hex');
  req.session.oauthState = state;
  res.redirect(buildDiscordAuthorizeUrl(state));
});

authRouter.get('/auth/callback', async (req, res, next) => {
  try {
    const code = typeof req.query.code === 'string' ? req.query.code : null;
    const state = typeof req.query.state === 'string' ? req.query.state : null;
    if (!code || !state || state !== req.session.oauthState) return res.status(400).send('Connexion Discord invalide.');

    const tokens = await exchangeCode(code);
    const user = await fetchDiscordUser(tokens.access_token);
    req.session.oauthState = undefined;
    req.session.discord = {
      accessToken: tokens.access_token,
      refreshToken: tokens.refresh_token,
      expiresAt: Date.now() + tokens.expires_in * 1000 - 60_000,
      user: {
        id: user.id,
        username: user.username,
        globalName: user.global_name,
        avatar: user.avatar
      }
    };
    res.redirect(`${env.BASE_PATH}/dashboard`);
  } catch (error) {
    next(error);
  }
});

authRouter.post('/logout', verifyCsrf, (req, res) => {
  req.session.destroy(() => res.redirect(`${env.BASE_PATH}/login`));
});
