<?php
// user_form.php — criar/editar usuários em modal
$title = 'Usuário';
require_once __DIR__ . '/auth.php';
require_login();
require_perm('users.*');
check_csrf();

$allowed_roles = ['ADMIN','TI','RH','AUDITOR','VIEWER'];
$id   = isset($_GET['id']) ? (int)$_GET['id'] : 0;
$edit = $id > 0;

// Carrega usuário (edição)
$userRow = null;
if ($edit) {
  $st = $pdo->prepare("SELECT * FROM users WHERE id=?");
  $st->execute([$id]);
  $userRow = $st->fetch();
  if (!$userRow) { http_response_code(404); exit('Usuário não encontrado'); }
}

$err = ''; $ok = '';

// POST
if ($_SERVER['REQUEST_METHOD']==='POST') {
  check_csrf();

  $name     = trim($_POST['name']     ?? '');
  $email    = strtolower(trim($_POST['email']    ?? ''));
  $username = strtolower(trim($_POST['username'] ?? ''));
  $role     = trim($_POST['role']     ?? 'VIEWER');
  $active   = isset($_POST['is_active']) ? 1 : 0;
  $pwd      = (string)($_POST['password']  ?? '');
  $pwd2     = (string)($_POST['password2'] ?? '');

  // Regras
  $username_ok = (bool)preg_match('~^[a-z0-9._-]{3,32}$~', $username);
  $name_ok     = mb_strlen($name) >= 3 && mb_strlen($name) <= 120;
  $email_ok    = $email !== '' && filter_var($email, FILTER_VALIDATE_EMAIL) && mb_strlen($email) <= 190;

  if (!$name_ok)                                   $err = 'Informe o nome (mín. 3 caracteres).';
  elseif (!$email_ok)                              $err = 'Informe um e-mail válido.';
  elseif (!$username_ok)                           $err = 'Usuário deve ter 3–32 caracteres (a–z, 0–9, ponto, hífen ou _).';
  elseif (!in_array($role,$allowed_roles,true))    $err = 'Papel inválido.';
  elseif (!$edit && $pwd === '')                   $err = 'Defina uma senha para o novo usuário.';
  elseif ($pwd !== '' && $pwd !== $pwd2)           $err = 'A confirmação de senha não confere.';
  elseif ($pwd !== '') {
    if (function_exists('validate_password_complexity')) {
      if ($m = validate_password_complexity($pwd)) $err = $m;
    } else {
      $hasLen = strlen($pwd) >= (defined('PWD_MIN_LEN') ? PWD_MIN_LEN : 8);
      $hasUp  = preg_match('/[A-Z]/',$pwd);
      $hasLo  = preg_match('/[a-z]/',$pwd);
      $hasDi  = preg_match('/\d/',$pwd);
      $hasSy  = preg_match('/[^A-Za-z0-9]/',$pwd);
      if (!($hasLen && $hasUp && $hasLo && $hasDi && $hasSy)) {
        $err = 'A senha precisa ter maiúscula, minúscula, número e símbolo.';
      }
    }
  }

  // Unicidade
  if ($err==='') {
    $st = $pdo->prepare("SELECT id FROM users WHERE username=? AND id<>?");
    $st->execute([$username, $id ?: 0]);
    if ($st->fetch()) $err = 'Este usuário (login) já existe.';
  }
  if ($err==='') {
    $st = $pdo->prepare("SELECT id FROM users WHERE email=? AND id<>?");
    $st->execute([$email, $id ?: 0]);
    if ($st->fetch()) $err = 'Este e-mail já está cadastrado para outro usuário.';
  }

  if ($err==='') {
    try {
      if ($edit) {
        $pdo->prepare("UPDATE users SET name=?, email=?, username=?, role=?, is_active=? WHERE id=?")
            ->execute([$name,$email,$username,$role,$active,$id]);
        if ($pwd!=='') {
          if (function_exists('set_user_password')) {
            set_user_password($pdo, $id, $pwd);
          } else {
            $hash = password_hash($pwd, PASSWORD_DEFAULT);
            if (db_has_col($pdo,'users','password_changed_at')) {
              $pdo->prepare("UPDATE users SET password_hash=?, password_changed_at=NOW() WHERE id=?")
                  ->execute([$hash,$id]);
            } else {
              $pdo->prepare("UPDATE users SET password_hash=? WHERE id=?")
                  ->execute([$hash,$id]);
            }
          }
        }
        $ok = 'Usuário atualizado com sucesso.';
        $st = $pdo->prepare("SELECT * FROM users WHERE id=?");
        $st->execute([$id]); $userRow = $st->fetch();
      } else {
        $hash = password_hash($pwd, PASSWORD_DEFAULT);
        if (db_has_col($pdo,'users','password_changed_at')) {
          $sql = "INSERT INTO users (name,email,username,role,is_active,password_hash,password_changed_at)
                  VALUES (?,?,?,?,?,?,NOW())";
          $pdo->prepare($sql)->execute([$name,$email,$username,$role,$active,$hash]);
        } else {
          $sql = "INSERT INTO users (name,email,username,role,is_active,password_hash)
                  VALUES (?,?,?,?,?,?)";
          $pdo->prepare($sql)->execute([$name,$email,$username,$role,$active,$hash]);
        }
        $newId = (int)$pdo->lastInsertId();
        header('Location: '.base_url('user_form.php?id='.$newId.'&ok=1')); exit;
      }
    } catch (Throwable $e) {
      $err = 'Erro ao salvar: ' . $e->getMessage();
    }
  }
}

// mensagem via GET pós-criação
if (!$err && isset($_GET['ok'])) $ok = 'Usuário criado com sucesso.';

// Preenche valores
$name     = $userRow['name']     ?? ($name     ?? '');
$email    = $userRow['email']    ?? ($email    ?? '');
$username = $userRow['username'] ?? ($username ?? '');
$role     = $userRow['role']     ?? ($role     ?? 'VIEWER');
$active   = isset($userRow['is_active']) ? (int)$userRow['is_active'] : ($active ?? 1);

include __DIR__ . '/header.php';
$back = base_url('users.php');
?>
<div class="container-fluid">
  <!-- Modal -->
  <div class="modal fade" id="userModal" tabindex="-1" aria-hidden="true" data-bs-backdrop="static">
    <div class="modal-dialog modal-lg modal-dialog-centered">
      <form class="modal-content" method="post" novalidate>
        <input type="hidden" name="csrf" value="<?= h(csrf_token()) ?>">
        <div class="modal-header">
          <h5 class="modal-title"><?= $edit ? 'Editar usuário' : 'Novo usuário' ?></h5>
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Fechar"></button>
        </div>

        <div class="modal-body">
          <?php if ($err): ?><div class="alert alert-danger"><?= h($err) ?></div><?php endif; ?>
          <?php if ($ok):  ?><div class="alert alert-success"><?= h($ok)  ?></div><?php endif; ?>

          <div class="row g-3">
            <div class="col-md-6">
              <label class="form-label">Nome completo</label>
              <div class="input-group">
                <span class="input-group-text"><i class="bi bi-person"></i></span>
                <input name="name" class="form-control" required value="<?= h($name) ?>" maxlength="120" autocomplete="name">
              </div>
            </div>

            <div class="col-md-6">
              <label class="form-label">E-mail</label>
              <div class="input-group">
                <span class="input-group-text"><i class="bi bi-envelope"></i></span>
                <input name="email" id="email" type="email" class="form-control" required
                       value="<?= h($email) ?>" inputmode="email" autocomplete="email" maxlength="190">
              </div>
              <div class="form-text">Minúsculas, sem espaços.</div>
            </div>

            <div class="col-md-5">
              <label class="form-label">Usuário (login)</label>
              <div class="input-group">
                <span class="input-group-text">@</span>
                <input name="username" id="username" class="form-control" required value="<?= h($username) ?>"
                       minlength="3" maxlength="32" autocomplete="username"
                       pattern="[a-z0-9._-]{3,32}" title="Use letras minúsculas, números, ponto, hífen ou _ (3–32).">
              </div>
              <div class="form-text">Ex.: joao.silva, m-oliveira, ti_admin.</div>
            </div>

            <div class="col-md-4">
              <label class="form-label">Papel</label>
              <select name="role" class="form-select">
                <?php foreach ($allowed_roles as $r): ?>
                  <option value="<?= h($r) ?>" <?= $role===$r?'selected':'' ?>><?= h($r) ?></option>
                <?php endforeach; ?>
              </select>
            </div>

            <div class="col-md-3 d-flex align-items-end">
              <div class="form-check">
                <input class="form-check-input" type="checkbox" name="is_active" id="act" <?= $active? 'checked':'' ?>>
                <label class="form-check-label" for="act">Ativo</label>
              </div>
            </div>

            <div class="col-md-6">
              <label class="form-label"><?= $edit ? 'Nova senha (opcional)' : 'Senha' ?></label>
              <div class="input-group">
                <span class="input-group-text"><i class="bi bi-shield-lock"></i></span>
                <input name="password" id="password" type="password" class="form-control" <?= $edit?'':'required' ?>
                       autocomplete="new-password">
                <button type="button" class="btn btn-outline-secondary" id="togglePwd"><i class="bi bi-eye"></i></button>
                <button type="button" class="btn btn-outline-primary" id="genPwd"><i class="bi bi-magic"></i> Gerar</button>
              </div>
              <div class="progress mt-2" style="height:6px;">
                <div id="pwdStrength" class="progress-bar" role="progressbar" style="width:0%"></div>
              </div>
              <div class="form-text">Mín. <?= defined('PWD_MIN_LEN') ? PWD_MIN_LEN : 8 ?>, com maiúscula, minúscula, número e símbolo.</div>
            </div>

            <div class="col-md-6">
              <label class="form-label"><?= $edit ? 'Confirmar nova senha' : 'Confirmar senha' ?></label>
              <div class="input-group">
                <span class="input-group-text"><i class="bi bi-shield-check"></i></span>
                <input name="password2" id="password2" type="password" class="form-control" <?= $edit?'':'required' ?>
                       autocomplete="new-password">
                <button type="button" class="btn btn-outline-secondary" id="togglePwd2"><i class="bi bi-eye"></i></button>
              </div>
            </div>
          </div>
        </div>

        <div class="modal-footer">
          <a href="<?= $back ?>" class="btn btn-outline-secondary" data-bs-dismiss="modal" id="btnClose">Fechar</a>
          <button class="btn btn-primary"><?= $edit ? 'Salvar alterações' : 'Criar usuário' ?></button>
        </div>
      </form>
    </div>
  </div>
</div>

<script>
// Abre modal ao carregar e, ao fechar, volta para a lista
document.addEventListener('DOMContentLoaded', function(){
  var el = document.getElementById('userModal');
  var m  = new bootstrap.Modal(el);
  m.show();
  el.addEventListener('hidden.bs.modal', function(){ window.location.href = <?= json_encode($back) ?>; });
});

// máscara email: minúsculas + sem espaços
const email = document.getElementById('email');
email?.addEventListener('input', (e) => {
  e.target.value = e.target.value.toLowerCase().replace(/\s+/g,'');
});

// máscara username: só a-z, 0-9, ponto, hífen, underline
const userInp = document.getElementById('username');
userInp?.addEventListener('input', (e) => {
  const v = e.target.value.toLowerCase().replace(/[^a-z0-9._-]/g,'');
  if (v !== e.target.value) e.target.value = v;
});

// sugestão automática de username
function slugifyName(n){
  return n.toLowerCase()
          .normalize('NFD').replace(/[\u0300-\u036f]/g,'')
          .replace(/[^a-z0-9]+/g,'.')
          .replace(/^\.+|\.+$/g,'')
          .replace(/\.+/g,'.')
          .slice(0,32);
}
function suggestUsername(){
  if (!userInp || userInp.value.trim()!=='') return;
  const em = email?.value.trim();
  if (em && em.includes('@')) {
    userInp.value = em.split('@')[0].replace(/[^a-z0-9._-]/g,'').slice(0,32);
    return;
  }
  const nm = document.querySelector('input[name="name"]')?.value || '';
  if (nm) userInp.value = slugifyName(nm);
}
email?.addEventListener('blur', suggestUsername);
document.querySelector('input[name="name"]')?.addEventListener('blur', suggestUsername);

// gerar senha forte
function genPassword(len=14){
  const a='ABCDEFGHJKLMNPQRSTUVWXYZ';
  const b='abcdefghijkmnopqrstuvwxyz';
  const c='23456789';
  const d='!@#$%&*?-_+=';
  const all=a+b+c+d;
  let s  = a[Math.floor(Math.random()*a.length)]
         + b[Math.floor(Math.random()*b.length)]
         + c[Math.floor(Math.random()*c.length)]
         + d[Math.floor(Math.random()*d.length)];
  for(let i=s.length;i<len;i++){ s += all[Math.floor(Math.random()*all.length)]; }
  return s.split('').sort(()=>Math.random()-0.5).join('');
}
const pwd  = document.getElementById('password');
const pwd2 = document.getElementById('password2');
document.getElementById('genPwd')?.addEventListener('click', ()=>{
  const p = genPassword();
  if (pwd)  pwd.value  = p;
  if (pwd2) pwd2.value = p;
  updateStrength();
});

// toggle visibilidade
function toggleVis(btn, input){
  btn?.addEventListener('click', ()=>{
    if (!input) return;
    input.type = input.type==='password' ? 'text' : 'password';
    btn.querySelector('i')?.classList.toggle('bi-eye');
    btn.querySelector('i')?.classList.toggle('bi-eye-slash');
  });
}
toggleVis(document.getElementById('togglePwd'),  pwd);
toggleVis(document.getElementById('togglePwd2'), pwd2);

// medidor de força
const bar = document.getElementById('pwdStrength');
function updateStrength(){
  if (!pwd || !bar) return;
  const v = pwd.value || '';
  let score = 0;
  const reqLen = <?= json_encode(defined('PWD_MIN_LEN') ? PWD_MIN_LEN : 8) ?>;
  if (v.length >= reqLen) score++;
  if (/[A-Z]/.test(v)) score++;
  if (/[a-z]/.test(v)) score++;
  if (/\d/.test(v)) score++;
  if (/[^A-Za-z0-9]/.test(v)) score++;
  const pct = [0,20,40,60,80,100][score];
  bar.style.width = pct + '%';
  bar.className = 'progress-bar ' + (pct>=80?'bg-success':pct>=60?'bg-info':pct>=40?'bg-warning':'bg-danger');
}
pwd?.addEventListener('input', updateStrength);
document.addEventListener('DOMContentLoaded', updateStrength);
</script>

<?php include __DIR__ . '/footer.php'; ?>

