import { Router } from 'express';
import bcrypt from 'bcryptjs';
import { requireTeacher } from './auth.js';
import { findUserByUsername, createUser, listStudents } from './db.js';

const router = Router();
const BCRYPT_ROUNDS = 8;
const USERNAME_RE = /^[a-zA-Z0-9_.-]{3,64}$/;

const WORDS_A = ['red', 'blue', 'green', 'happy', 'sunny', 'brave', 'tiny', 'swift', 'kind', 'bright'];
const WORDS_B = ['cat', 'dog', 'fox', 'duck', 'frog', 'bear', 'star', 'moon', 'kite', 'fish'];
const WORDS_C = ['jump', 'play', 'run', 'smile', 'spin', 'dance', 'wave', 'clap', 'sing', 'grow'];

function sanitizeStudent(row) {
  return {
    id: row.id,
    username: row.username,
    role: row.role,
    createdAt: row.created_at,
  };
}

function randomItem(list) {
  return list[Math.floor(Math.random() * list.length)];
}

function candidateUsername() {
  const useThree = Math.random() < 0.45;
  const first = randomItem(WORDS_A);
  const second = randomItem(WORDS_B);
  if (!useThree) return `${first}${second}`;
  const third = randomItem(WORDS_C);
  return `${first}${second}${third}`;
}

async function generateUniqueUsername() {
  for (let i = 0; i < 40; i += 1) {
    const candidate = candidateUsername();
    const existing = await findUserByUsername(candidate);
    if (!existing) return candidate;
  }
  return `${candidateUsername()}${Math.floor(100 + Math.random() * 900)}`;
}

router.get('/students', requireTeacher, async (_req, res) => {
  try {
    const students = (await listStudents()).map(sanitizeStudent);
    res.json({ students });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.get('/students/suggest-username', requireTeacher, async (_req, res) => {
  try {
    const username = await generateUniqueUsername();
    res.json({ username });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

router.post('/students', requireTeacher, async (req, res) => {
  let { username } = req.body || {};
  try {
    username = username ? String(username).trim() : '';
    if (!username) username = await generateUniqueUsername();
    if (!USERNAME_RE.test(username)) {
      return res.status(400).json({ error: 'username must be 3-64 chars, letters/digits/._-' });
    }
    const existing = await findUserByUsername(username);
    if (existing) return res.status(409).json({ error: 'username already taken' });

    // Requested behavior: default password equals username.
    const hash = await bcrypt.hash(username, BCRYPT_ROUNDS);
    const user = await createUser({ username, passwordHash: hash, role: 'student' });
    res.json({ student: sanitizeStudent(user), defaultPassword: username });
  } catch (err) {
    res.status(500).json({ error: err.message });
  }
});

export default router;
