# frozen_string_literal: true

module RedmineUxToolkit
  module Patches
    module AccountControllerPatch
      # Redmine exposes a successful-login hook but not a hook for changing only
      # the default redirect target. Redmine's login form may also submit a
      # referer-derived back_url for ordinary sign-ins, so this patch tracks only
      # explicit login back_url values as protected original targets.
      def login
        redmine_ux_toolkit_store_explicit_login_back_url unless request.post?
        super
      end

      def redirect_back_or_default(default, options = {})
        if redmine_ux_toolkit_login_default_redirect?(default, options)
          redmine_ux_toolkit_redirect_after_login(default)
        else
          super
        end
      end

      def successful_authentication(user)
        logger.info "Successful authentication for '#{user.login}' from #{request.remote_ip} at #{Time.now.utc}"
        self.logged_user = user

        if params[:autologin] && Setting.autologin?
          set_autologin_cookie(user)
        end

        call_hook(:controller_account_success_authentication_after, {user: user})
        redirect_back_or_default my_page_path
      end

      private

      def redmine_ux_toolkit_login_default_redirect?(default, options)
        request.post? &&
          options.blank? &&
          default == my_page_path &&
          User.current.logged?
      end

      def redmine_ux_toolkit_redirect_after_login(default)
        target = redmine_ux_toolkit_explicit_login_back_url ||
                 RedmineUxToolkit::Services::LandingPageResolver.new(User.current).path ||
                 default

        Rails.logger.info "Redmine UX Toolkit login redirect target: #{target}"
        redirect_to target
      ensure
        session[:redmine_ux_toolkit_login_back_url] = nil
      end

      def redmine_ux_toolkit_store_explicit_login_back_url
        session[:redmine_ux_toolkit_login_back_url] = validate_back_url(params[:back_url].to_s) || nil
      end

      def redmine_ux_toolkit_explicit_login_back_url
        stored_back_url = validate_back_url(session[:redmine_ux_toolkit_login_back_url].to_s)
        posted_back_url = validate_back_url(params[:back_url].to_s)

        stored_back_url if stored_back_url.present? && stored_back_url == posted_back_url
      end
    end
  end
end
