const express = require('express');
const bcrypt  = require('bcryptjs');
const fs      = require('fs');
const path    = require('path');
const router  = express.Router();
const authMw  = require('../middleware/auth');
const { writeAudit } = require('./audit');

const DB = path.join(__dirname, '../data/users.json');
const ALL_PERMS    = ['dashboard','processes','sites','ssl','services','database','query','dbusers','files','logs','smtp','domains','users','settings'];
const VIEWER_PERMS = ['dashboard','processes','sites','ssl','services','files','logs'];

function load() {
  if (!fs.existsSync(path.dirname(DB))) fs.mkdirSync(path.dirname(DB), { recursive: true });
  if (!fs.existsSync(DB)) {
    const seed = [{
      id: 1,
      username: process.env.ADMIN_USER || 'admin',
      password: process.env.ADMIN_PASS_HASH || bcrypt.hashSync('admin123', 10),
      role: 'admin', permissions: ALL_PERMS, createdAt: new Date().toISOString()
    }];
    fs.writeFileSync(DB, JSON.stringify(seed, null, 2));
  }
  return JSON.parse(fs.readFileSync(DB));
}
function save(u) { fs.writeFileSync(DB, JSON.stringify(u, null, 2)); }
function adminOnly(req, res, next) {
  if (req.user.role !== 'admin') return res.status(403).json({ error: 'Admin only' });
  next();
}

// ── List users ─────────────────────────────────────────────
router.get('/', authMw, adminOnly, (req, res) => {
  res.json(load().map(u => ({
    id: u.id, username: u.username, role: u.role,
    permissions: u.permissions || ALL_PERMS, createdAt: u.createdAt
  })));
});

// ── Create user ────────────────────────────────────────────
router.post('/', authMw, adminOnly, (req, res) => {
  const { username, password, role, permissions } = req.body;
  if (!username || !password) return res.status(400).json({ error: 'Username and password required' });
  if (!['admin', 'viewer'].includes(role)) return res.status(400).json({ error: 'Role must be admin or viewer' });
  const users = load();
  if (users.find(u => u.username === username)) return res.status(400).json({ error: 'Username already exists' });
  const perms = role === 'admin' ? ALL_PERMS : (permissions || VIEWER_PERMS);
  const user  = { id: Date.now(), username, password: bcrypt.hashSync(password, 10), role, permissions: perms, createdAt: new Date().toISOString() };
  users.push(user);
  save(users);
  writeAudit(req, 'users.create', `Created user "${username}" (${role})`);
  res.json({ ok: true });
});

// ── Update permissions ─────────────────────────────────────
router.put('/:id/permissions', authMw, adminOnly, (req, res) => {
  const users = load();
  const user  = users.find(u => u.id === parseInt(req.params.id));
  if (!user) return res.status(404).json({ error: 'User not found' });
  user.permissions = req.body.permissions || [];
  save(users);
  writeAudit(req, 'users.permissions', `Updated permissions for "${user.username}": ${user.permissions.join(', ')}`);
  res.json({ ok: true });
});

// ── Change password ────────────────────────────────────────
// Any user can change their own password; admin can change anyone's.
router.post('/:id/password', authMw, (req, res) => {
  const id = parseInt(req.params.id);
  if (req.user.role !== 'admin' && req.user.id !== id)
    return res.status(403).json({ error: 'You can only change your own password' });

  const { currentPassword, password } = req.body;

  // Non-admins must supply their current password for verification
  if (req.user.role !== 'admin' && !currentPassword)
    return res.status(400).json({ error: 'Current password is required' });

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

  const users = load();
  const user  = users.find(u => u.id === id);
  if (!user) return res.status(404).json({ error: 'User not found' });

  // Verify current password for non-admins
  if (req.user.role !== 'admin') {
    if (!bcrypt.compareSync(currentPassword, user.password))
      return res.status(401).json({ error: 'Current password is incorrect' });
  }

  user.password = bcrypt.hashSync(password, 10);
  save(users);
  const changer = req.user.username;
  const target  = user.username;
  writeAudit(req, 'users.password', changer === target ? `"${target}" changed their own password` : `Admin "${changer}" changed password for "${target}"`);
  res.json({ ok: true });
});

// ── Delete user ────────────────────────────────────────────
router.delete('/:id', authMw, adminOnly, (req, res) => {
  if (parseInt(req.params.id) === 1) return res.status(400).json({ error: 'Cannot delete default admin' });
  const users  = load();
  const target = users.find(u => u.id === parseInt(req.params.id));
  save(users.filter(u => u.id !== parseInt(req.params.id)));
  writeAudit(req, 'users.delete', `Deleted user "${target ? target.username : req.params.id}"`);
  res.json({ ok: true });
});

module.exports = router;