# app/controllers/usuarios_controller.rb
class Admin::UsuariosController < ApplicationController
  before_action :set_usuario, only: [:show, :edit, :update, :destroy, :toggle_ativo]

  def index
    authorize User
    @usuarios = policy_scope(User).includes(:perfil_acesso).order(:nome).limit(200)
    @roles = User.roles.keys
  end

  def show
    authorize @usuario
  end

  def new
    @usuario = User.new
    authorize @usuario
  end

  def create
    @usuario = User.new(usuario_params)
    authorize @usuario

    if @usuario.save
      AuditoriaLog.registrar(user: current_user, acao: 'criar_usuario', entidade: 'User', dados_novos: { detalhes: "Criou usuário #{@usuario.email} (#{@usuario.role})" }, request: request)
      redirect_to admin_usuarios_path, notice: 'Usuário criado com sucesso.'
    else
      render :new, status: :unprocessable_entity
    end
  end

  def edit
    authorize @usuario
  end

  def update
    authorize @usuario

    # Trava do último administrador: mudar perfil ou desativar a única pessoa que
    # ainda administra acesso deixaria o sistema sem quem conserte.
    if desligaria_o_ultimo_administrador?
      @usuario.errors.add(:base, MENSAGEM_ULTIMO_ADMIN)
      return render(:edit, status: :unprocessable_entity)
    end

    if @usuario.update(usuario_params_update)
      AuditoriaLog.registrar(user: current_user, acao: 'editar_usuario', entidade: 'User', dados_novos: { detalhes: "Editou usuário #{@usuario.email}" }, request: request)
      redirect_to admin_usuarios_path, notice: 'Usuário atualizado.'
    else
      render :edit, status: :unprocessable_entity
    end
  end

  def destroy
    authorize @usuario

    if User.ultimo_administrador?(@usuario)
      return redirect_to(admin_usuarios_path, alert: MENSAGEM_ULTIMO_ADMIN)
    end

    if @usuario == current_user
      redirect_to admin_usuarios_path, alert: 'Você não pode excluir sua própria conta.'
      return
    end

    @usuario.destroy
    AuditoriaLog.registrar(user: current_user, acao: 'excluir_usuario', entidade: 'User', dados_novos: { detalhes: "Excluiu usuário #{@usuario.email}" }, request: request)
    redirect_to admin_usuarios_path, notice: 'Usuário removido.'
  end

  def toggle_ativo
    authorize @usuario, :toggle_ativo?

    if @usuario.ativo? && User.ultimo_administrador?(@usuario)
      return redirect_to(admin_usuarios_path, alert: MENSAGEM_ULTIMO_ADMIN)
    end
    @usuario.update!(ativo: !@usuario.ativo)
    status = @usuario.ativo? ? 'ativado' : 'desativado'
    AuditoriaLog.registrar(user: current_user, acao: "usuario_#{status}", entidade: 'User', dados_novos: { detalhes: "#{@usuario.email} foi #{status}" }, request: request)
    redirect_to admin_usuarios_path, notice: "Usuário #{status} com sucesso."
  end

  private

  MENSAGEM_ULTIMO_ADMIN = 'Esta alteração deixaria o sistema sem nenhum usuário ativo capaz de ' \
                          'gerenciar perfis e usuários. Dê esse acesso a outra pessoa antes.'.freeze

  def set_usuario
    @usuario = User.find(params[:id])
  end

  # Aplica as mudanças em memória e pergunta: sobra alguém administrando?
  def desligaria_o_ultimo_administrador?
    simulado = @usuario.dup
    simulado.id = @usuario.id
    simulado.assign_attributes(usuario_params_update)
    simulado.recarregar_permissoes!

    return false if simulado.ativo? && simulado.pode?('admin.perfis') && simulado.pode?('admin.usuarios_gerenciar')

    User.ultimo_administrador?(@usuario)
  end

  # ⚠️ CAMPOS DE ACESSO SÓ PARA QUEM PODE MEXER NELES.
  # `UserPolicy#update?` libera editar a PRÓPRIA ficha (nome, senha) — é o que
  # permite alguém trocar a própria senha. Sem o filtro abaixo, essa mesma
  # permissão deixava qualquer usuário logado enviar `user[role]=admin` na edição
  # do próprio cadastro e se promover. Quem decide papel e perfil é
  # `UserPolicy#alterar_acesso?` (nunca sobre si mesmo).
  CAMPOS_DE_ACESSO = %i[role perfil_acesso_id ativo].freeze

  def usuario_params
    permitidos = [:nome, :email, :password, :password_confirmation, :pin_code]
    permitidos += CAMPOS_DE_ACESSO if pode_alterar_acesso?
    params.require(:user).permit(permitidos)
  end

  def usuario_params_update
    permitidos = [:nome, :email, :pin_code]
    permitidos += CAMPOS_DE_ACESSO if pode_alterar_acesso?
    permitidos += [:password, :password_confirmation] if params[:user][:password].present?
    params.require(:user).permit(permitidos)
  end

  def pode_alterar_acesso?
    if @usuario&.persisted?
      policy(@usuario).alterar_acesso?
    else
      # Criação: não há "si mesmo" para se promover, basta poder gerenciar.
      current_user.pode?('admin.usuarios_gerenciar')
    end
  end
  helper_method :pode_alterar_acesso?
end
