import mysql from 'mysql2/promise';

let pool = null;

export function getPool() {
  if (pool) return pool;
  pool = mysql.createPool({
    host: process.env.MYSQL_HOST || 'localhost',
    port: Number(process.env.MYSQL_PORT) || 3306,
    user: process.env.MYSQL_USER || 'root',
    password: process.env.MYSQL_PASSWORD || '',
    database: process.env.MYSQL_DATABASE || 'esp32block',
    waitForConnections: true,
    connectionLimit: 8,
    queueLimit: 0,
    charset: 'utf8mb4',
  });
  return pool;
}

export async function bootstrap() {
  const db = getPool();
  await db.query(`
    CREATE TABLE IF NOT EXISTS users (
      id INT PRIMARY KEY AUTO_INCREMENT,
      username VARCHAR(64) NOT NULL UNIQUE,
      password_hash VARCHAR(255) NOT NULL,
      role ENUM('student','teacher') NOT NULL DEFAULT 'student',
      created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  `);
  await db.query(`
    CREATE TABLE IF NOT EXISTS sessions (
      token CHAR(48) PRIMARY KEY,
      user_id INT NOT NULL,
      expires_at DATETIME NOT NULL,
      INDEX idx_sessions_user (user_id),
      CONSTRAINT fk_sessions_user FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
  `);
}

export async function findUserByUsername(username) {
  const [rows] = await getPool().query(
    'SELECT id, username, password_hash, role FROM users WHERE username = ? LIMIT 1',
    [username],
  );
  return rows[0] || null;
}

export async function findUserById(id) {
  const [rows] = await getPool().query(
    'SELECT id, username, role FROM users WHERE id = ? LIMIT 1',
    [id],
  );
  return rows[0] || null;
}

export async function createUser({ username, passwordHash, role = 'student' }) {
  const [result] = await getPool().query(
    'INSERT INTO users (username, password_hash, role) VALUES (?, ?, ?)',
    [username, passwordHash, role],
  );
  return { id: result.insertId, username, role };
}

export async function createSession({ token, userId, expiresAt }) {
  await getPool().query(
    'INSERT INTO sessions (token, user_id, expires_at) VALUES (?, ?, ?)',
    [token, userId, expiresAt],
  );
}

export async function findSession(token) {
  const [rows] = await getPool().query(
    `SELECT s.token, s.user_id, s.expires_at, u.username, u.role
       FROM sessions s
       JOIN users u ON u.id = s.user_id
      WHERE s.token = ? AND s.expires_at > NOW()
      LIMIT 1`,
    [token],
  );
  return rows[0] || null;
}

export async function deleteSession(token) {
  await getPool().query('DELETE FROM sessions WHERE token = ?', [token]);
}

export async function purgeExpiredSessions() {
  await getPool().query('DELETE FROM sessions WHERE expires_at <= NOW()');
}
