module Symphonia
  class UsersController < ApplicationController

    helper Symphonia::RendererHelper
    include ::CanCan::ControllerAdditions

    before_action :user, except: %i[index new create show]
    before_action :authorize, except: [:show]

    def index
      @query = Symphonia::User.query.new
      @query.from_params params
      @entities = @query.entities
      respond_to do |format|
        format.html do
          @entities = @entities.page(params[:page])
          render layout: !request.xhr?
        end
        format.json { render json: @entities.all, only: %i[id] + Symphonia::User.registered_attributes.keys }
      end
    end

    def show
      @user = Symphonia::User.find(params[:id]) if params[:id]
      @user ||= current_user
      authorize! :show, @user
      respond_to do |format|
        format.html
        format.json { render json: @user, except: %w[crypted_password password_salt persistence_token perishable_token] }
      end
    end

    def new
      @user = Symphonia::User.new
      respond_to do |format|
        format.html
      end
    end

    def create
      @user = Symphonia::User.new(user_params)
      respond_to do |format|
        if @user.save
          format.html { redirect_to @user, notice: t(:text_created) }
          format.xml { render xml: @user, status: :created, location: @user }
          format.json { render json: @user, status: :created, location: @user }
        else
          format.html { render action: 'new' }
          format.xml { render xml: @user.errors, status: :unprocessable_entity }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end

    def edit; end

    def update
      @user.attributes = user_params
      @user.admin = params[:admin] if params[:admin] && current_user.admin?
      respond_to do |format|
        @user.edited_by = current_user
        @user.edited_at = DateTime.now
        if @user.save
          format.html { redirect_back_or_default user_path(@user), notice: t(:text_updated) }
          format.any(:json, :xml) { head :no_content }
        else
          format.html { render action: 'edit' }
          format.xml { render xml: @user.errors, status: :unprocessable_entity }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end

    def destroy
      @user.destroy

      respond_to do |format|
        format.html { redirect_to params[:back_url] || users_url }
        format.js { render js: "Symphonia.filters.removeRow('#{view_context.dom_id(@user)}')" }
        format.json { head :no_content }
      end
    end

    def archive
      @user.archive!
      respond_to do |format|
        format.html { redirect_to params[:back_url] || users_url }
        format.json { head :no_content }
      end
    end

    def unarchive
      Notifier.user_change_to_active(@user).deliver_later
      @user.unarchive!

      respond_to do |format|
        format.html { redirect_to params[:back_url] || users_url }
        format.xml { head :no_content }
      end
    end

    private

    def user
      @user ||= Symphonia::User.find(params[:id])
    end

    def authorize
      authorize! action_name.to_sym, @user
    end

    def user_params
      allowed = [:login, :first_name, :last_name, :password, :password_confirmation, :email, :mail, preference_ids: []]
      allowed << :admin if current_user.admin?
      params.require(:user).permit(allowed)
    end

    def current_ability
      @current_ability ||= UserAbility.new current_user
    end

  end
end