/**
 * ID Generator Service
 * Generates institutional IDs based on role, institution initials, and year.
 */

const getDb = () => {
  const dbPath = process.env.DB_PATH || require('path').join(__dirname, '../../data/school.db');
  const Database = require('better-sqlite3');
  return new Database(dbPath);
};

/**
 * Generates the next institutional ID.
 * Format: [RoleInitial][InstInitials][Year][SequentialCode]
 * Example: SAA2600001 (Student, Africa Alert, 2026, 00001)
 * 
 * @param {string} role - User role
 * @param {Date} [date] - Optional date to determine year (defaults to current)
 * @returns {Promise<string>}
 */
async function generateId(role, date = new Date()) {
  const db = getDb();
  
  // 1. Get Role Initial
  const roleInitial = (role === 'student' ? 'S' : (role === 'teacher' ? 'T' : 'A'));
  
  // 2. Get Institution Initials
  let instInitials = 'AA'; // Fallback
  try {
    const settings = db.prepare('SELECT value FROM settings WHERE key = ? OR key = ? LIMIT 1').get('institution_name', 'school_name');
    if (settings && settings.value) {
      instInitials = settings.value
        .split(' ')
        .map(word => word[0])
        .join('')
        .toUpperCase()
        .slice(0, 3);
    }
  } catch (e) {
    console.error('Error fetching institution name for ID generation:', e);
  }
  
  // 3. Get Year (last 2 digits) from provided date
  const year = date.getFullYear().toString().slice(-2);
  
  const prefix = `${roleInitial}${instInitials}${year}`;
  
  // 4. Find the last ID with this prefix
  const lastUser = db.prepare(`
    SELECT id_number FROM users 
    WHERE id_number LIKE ? 
    ORDER BY id_number DESC LIMIT 1
  `).get(`${prefix}%`);
  
  let nextCode = '00001';
  
  if (lastUser && lastUser.id_number) {
    const lastCode = lastUser.id_number.slice(prefix.length);
    nextCode = incrementCode(lastCode);
  }
  
  return `${prefix}${nextCode}`;
}

/**
 * Increments a base-36 sequential code (0-9, A-Z).
 * Supports 5 digits.
 * 
 * @param {string} code 
 * @returns {string}
 */
function incrementCode(code) {
  const chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ';
  let num = 0;
  
  // Convert from base-36
  for (let i = 0; i < code.length; i++) {
    num = num * 36 + chars.indexOf(code[i]);
  }
  
  num++;
  
  // Convert back to base-36
  let nextCode = '';
  for (let i = 0; i < 5; i++) {
    nextCode = chars[num % 36] + nextCode;
    num = Math.floor(num / 36);
  }
  
  return nextCode;
}

module.exports = { generateId };
