import { Router, Request, Response } from 'express';
import { authService } from '../services/auth';
import { prisma } from '../db/prisma';
import { requireAuth } from '../middleware/auth';
import { normalizePubkey } from '../services/pubkey';

const router = Router();

router.post('/challenge', async (req: Request, res: Response) => {
  try {
    const { pubkey } = req.body;
    if (!pubkey || typeof pubkey !== 'string') {
      res.status(400).json({ error: 'pubkey is required' });
      return;
    }

    const challenge = authService.createChallenge(pubkey);
    res.json({ challenge });
  } catch (err) {
    console.error('Challenge error:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

router.post('/verify', async (req: Request, res: Response) => {
  try {
    const { pubkey, signedEvent } = req.body;
    if (!pubkey || !signedEvent) {
      res.status(400).json({ error: 'pubkey and signedEvent are required' });
      return;
    }

    const valid = authService.verifySignature(pubkey, signedEvent);
    if (!valid) {
      res.status(401).json({ error: 'Invalid signature or expired challenge' });
      return;
    }

    // Ensure a user row exists, but never overwrite an existing role on login.
    // The role is managed only through role assignment, and SuperAdmin is env-sourced.
    // Store the pubkey as hex so the same identity is never duplicated as npub.
    const hexPubkey = normalizePubkey(pubkey);
    const dbUser = await prisma.user.upsert({
      where: { pubkey: hexPubkey },
      update: {},
      create: { pubkey: hexPubkey },
    });

    const access = await authService.resolveAccess(pubkey);

    // The token carries a display role for convenience only. Authorization is
    // always resolved live from the env list and the database.
    const token = authService.generateToken(pubkey, access.role);
    res.json({
      token,
      user: {
        pubkey,
        role: access.role,
        isSuperAdmin: access.isSuperAdmin,
        permissions: [...access.permissions],
        username: dbUser.username ?? undefined,
      },
    });
  } catch (err) {
    console.error('Verify error:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

// Returns the current user's live effective role and permission set, for
// frontend gating. Identity comes from the JWT, authorization is resolved fresh.
router.get('/me', requireAuth, async (req: Request, res: Response) => {
  try {
    const pubkey = req.user!.pubkey;
    const access = await authService.resolveAccess(pubkey);
    const dbUser = await prisma.user.findUnique({ where: { pubkey } });
    res.json({
      pubkey,
      role: access.role,
      isSuperAdmin: access.isSuperAdmin,
      permissions: [...access.permissions],
      username: dbUser?.username ?? undefined,
    });
  } catch (err) {
    console.error('Me error:', err);
    res.status(500).json({ error: 'Internal server error' });
  }
});

export default router;
