module Symphonia
  class AccountsController < ApplicationController

    before_action :login_require, only: [:show, :edit, :update]
    before_action -> { menu_item(:my_account) }, only: [:show, :edit, :update]
    before_action :prepare_user, only: [:register, :create]

    def show
      @user = current_account

      respond_to do |format|
        format.html { render(template: "#{@user.class.name.underscore.pluralize}/show") }
        format.json { render json: @user }
      end
    end

    def register
      menu_item(:register)
    end

    def create
      menu_item(:register)
      @user.attributes = user_params
      @user.status = if Symphonia.config[:self_activation_enabled]
                       :active
                     else
                       :pending
                     end
      respond_to do |format|
        if @user.valid? && verify_registration && @user.save(validate: false)
          Notifier.activation_user(@user).deliver_later
          Notifier.user_registered(@user).deliver_later
          format.html { redirect_to login_path, notice: t(:text_user_registered) }
          format.json { render status: :created }
        else
          format.html { render action: 'register' }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end

    def edit
      @user = current_account
    end

    def update
      @user = current_account
      @user.attributes = user_params
      respond_to do |format|
        @user.edited_by = User.current.logged_in? && User.current
        @user.edited_at = Time.current
        if @user.save
          format.html { redirect_to({ action: 'show' }, notice: t(:text_updated)) }
          format.json { head :no_content }
          format.js
        else
          format.html { render action: 'edit' }
          format.json { render json: @user.errors, status: :unprocessable_entity }
        end
      end
    end

    #----

    def new_activation
    end

    def resend_activation
      @user = find_account_by_mail(params.require(:email))
      if @user
        if @user.active?
          redirect_to login_path, flash: { error: t(:text_user_alerady_active) }
        else
          @user.reset_perishable_token!
          Notifier.activation_user(@user).deliver_later
          redirect_to login_path, notice: t(:text_activation_resend)
        end
      else
        redirect_to login_path, flash: { error: t(:text_user_not_found) }
      end
    end

    def activation
      @user = find_account_by_token(params[:activation_code])
      if @user
        @user.activate!
        redirect_to login_path, notice: t(:text_activation_success)
      else
        redirect_to login_path, flash: { error: t(:text_user_not_found_or_token_invalid) }
      end
    end

    def current

    end

    def admin

    end

    # @!group Reset lost password

    def reset_password
      @user = find_account_by_token(params.require(:id))
      return render_404 if @user.nil?

      if params[:password].present?
        @user.password = params[:password]
      end

      if @user.changed? && @user.save
        logger.info "#{@user.id} has changed password"
        return redirect_to(login_path, notice: t(:text_password_reset_success))
      end
    end

    def lost_password
      @user = find_account_by_mail(params[:email]) if params[:email]
      if @user&.active?
        @user.reset_perishable_token!
        activation_url = url_for(action: "reset_password", id: @user.perishable_token, only_path: false)
        Notifier.reset_password_user(@user, activation_url).deliver_later
      end
      respond_to do |format|
        format.html do
          redirect_to login_path, notice: t(:text_reset_password_resend)
        end
        format.js
      end
    end

    # @!endgroup

    private

    def prepare_user
      return render_403 unless Symphonia.config[:allow_registrations]

      @user = User.new
    end

    def user_params
      params.require(:user).permit(:login, :name, :first_name, :last_name, :password, :password_confirmation, :email, :mail, preference_ids: [])
    end

    def current_account
      User.current
    end

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

    def find_account_by_mail(mail)
      User.find_by(email: mail)
    end

    def find_account_by_token(id)
      User.find_using_perishable_token(id, 1.week)
    end

    # @return [Boolean]
    def verify_registration
      true
    end

  end

end