const express = require('express');
const router = express.Router();
const bcrypt = require('bcryptjs');
const jwt = require('jsonwebtoken');
const { v4: uuidv4 } = require('uuid');
const { getDb } = require('../database');
const { logAction } = require('../utils/audit');
const {
  sendApprovalNotification,
  sendNewUserNotification,
  sendPasswordResetEmail
} = require('../utils/email');

const JWT_SECRET = process.env.JWT_SECRET || 'layerfive_secret_2024';
const JWT_EXPIRES = process.env.JWT_EXPIRES_IN || '8h';

// POST /api/auth/signup
router.post('/signup', (req, res) => {
  const { full_name, department, email, password } = req.body;
  if (!full_name || !department || !email || !password)
    return res.status(400).json({ error: 'All fields are required' });

  if (password.length < 6)
    return res.status(400).json({ error: 'Password must be at least 6 characters' });

  const db = getDb();
  const existing = db.prepare('SELECT id FROM users WHERE email = ?').get(email.toLowerCase());
  if (existing) return res.status(409).json({ error: 'Email already registered' });

  const hash = bcrypt.hashSync(password, 10);
  const result = db.prepare(`
    INSERT INTO users (full_name, department, email, password_hash, role, status)
    VALUES (?, ?, ?, ?, 'staff', 'pending')
  `).run(full_name.trim(), department.trim(), email.toLowerCase().trim(), hash);

  logAction(result.lastInsertRowid, email, full_name, 'SIGNUP', 'New user registration - pending approval', req);

  // Notify admins
  const admins = db.prepare("SELECT email FROM users WHERE role = 'admin' AND status = 'active'").all();
  admins.forEach(admin => sendNewUserNotification(admin.email, { full_name, email, department }).catch(() => {}));

  res.json({ message: 'Registration successful. Awaiting admin approval.' });
});

// POST /api/auth/login
router.post('/login', (req, res) => {
  const { email, password, remember_me } = req.body;
  if (!email || !password) return res.status(400).json({ error: 'Email and password required' });

  const db = getDb();
  const user = db.prepare('SELECT * FROM users WHERE email = ?').get(email.toLowerCase().trim());

  if (!user || !bcrypt.compareSync(password, user.password_hash)) {
    logAction(null, email, '', 'LOGIN_FAILED', `Failed login attempt for ${email}`, req);
    return res.status(401).json({ error: 'Invalid email or password' });
  }

  if (user.status === 'pending')
    return res.status(403).json({ error: 'Your account is pending admin approval.' });
  if (user.status === 'suspended')
    return res.status(403).json({ error: 'Your account has been suspended. Contact admin.' });

  const expiresIn = remember_me ? '30d' : JWT_EXPIRES;
  const token = jwt.sign({ id: user.id, email: user.email, role: user.role }, JWT_SECRET, { expiresIn });

  db.prepare('UPDATE users SET last_login = CURRENT_TIMESTAMP WHERE id = ?').run(user.id);
  logAction(user.id, user.email, user.full_name, 'LOGIN', 'User logged in successfully', req);

  res.json({
    token,
    user: {
      id: user.id,
      full_name: user.full_name,
      email: user.email,
      role: user.role,
      department: user.department,
      status: user.status
    }
  });
});

// POST /api/auth/logout
router.post('/logout', (req, res) => {
  const authHeader = req.headers.authorization;
  if (authHeader) {
    try {
      const token = authHeader.split(' ')[1];
      const decoded = jwt.verify(token, JWT_SECRET);
      const db = getDb();
      const user = db.prepare('SELECT full_name, email FROM users WHERE id = ?').get(decoded.id);
      if (user) logAction(decoded.id, user.email, user.full_name, 'LOGOUT', 'User logged out', req);
    } catch (_) {}
  }
  res.json({ message: 'Logged out successfully' });
});

// POST /api/auth/forgot-password
router.post('/forgot-password', (req, res) => {
  const { email } = req.body;
  if (!email) return res.status(400).json({ error: 'Email is required' });

  const db = getDb();
  const user = db.prepare('SELECT * FROM users WHERE email = ?').get(email.toLowerCase().trim());

  // Always respond success to prevent email enumeration
  if (!user) return res.json({ message: 'If that email exists, a reset link has been sent.' });

  const token = uuidv4();
  const expires = new Date(Date.now() + 3600000).toISOString(); // 1 hour

  db.prepare(`
    INSERT INTO password_reset_tokens (user_id, token, expires_at)
    VALUES (?, ?, ?)
  `).run(user.id, token, expires);

  sendPasswordResetEmail(user, token).catch(() => {});
  logAction(user.id, user.email, user.full_name, 'PASSWORD_RESET_REQUESTED', 'Password reset email sent', req);

  res.json({ message: 'If that email exists, a reset link has been sent.' });
});

// POST /api/auth/reset-password
router.post('/reset-password', (req, res) => {
  const { token, password } = req.body;
  if (!token || !password) return res.status(400).json({ error: 'Token and password required' });
  if (password.length < 6) return res.status(400).json({ error: 'Password must be at least 6 characters' });

  const db = getDb();
  const record = db.prepare(`
    SELECT * FROM password_reset_tokens
    WHERE token = ? AND used = 0 AND expires_at > CURRENT_TIMESTAMP
  `).get(token);

  if (!record) return res.status(400).json({ error: 'Invalid or expired reset token' });

  const hash = bcrypt.hashSync(password, 10);
  db.prepare('UPDATE users SET password_hash = ?, updated_at = CURRENT_TIMESTAMP WHERE id = ?').run(hash, record.user_id);
  db.prepare('UPDATE password_reset_tokens SET used = 1 WHERE id = ?').run(record.id);

  const user = db.prepare('SELECT email, full_name FROM users WHERE id = ?').get(record.user_id);
  if (user) logAction(record.user_id, user.email, user.full_name, 'PASSWORD_RESET', 'Password reset successfully', req);

  res.json({ message: 'Password reset successfully. You can now log in.' });
});

// GET /api/auth/me
router.get('/me', (req, res) => {
  const authHeader = req.headers.authorization;
  if (!authHeader) return res.status(401).json({ error: 'No token' });
  try {
    const token = authHeader.split(' ')[1];
    const decoded = jwt.verify(token, JWT_SECRET);
    const db = getDb();
    const user = db.prepare('SELECT id, full_name, email, role, department, status, created_at, last_login FROM users WHERE id = ?').get(decoded.id);
    if (!user || user.status !== 'active') return res.status(401).json({ error: 'Unauthorized' });
    res.json({ user });
  } catch {
    res.status(401).json({ error: 'Invalid token' });
  }
});

module.exports = router;
