# frozen_string_literal: true

module RedmineUxToolkit
  module Compatibility
    module_function

    def to_prepare(&block)
      if Rails.application.respond_to?(:reloader) &&
          Rails.application.reloader.respond_to?(:to_prepare)
        Rails.application.reloader.to_prepare(&block)
      elsif Rails.application.config.respond_to?(:to_prepare)
        Rails.application.config.to_prepare(&block)
      elsif defined?(ActiveSupport::Reloader)
        ActiveSupport::Reloader.to_prepare(&block)
      else
        block.call
      end
    end

    def issue_closed?(issue_or_status)
      return false unless issue_or_status

      if issue_or_status.respond_to?(:closed?)
        issue_or_status.closed?
      elsif issue_or_status.respond_to?(:is_closed?)
        issue_or_status.is_closed?
      elsif issue_or_status.respond_to?(:is_closed)
        issue_or_status.is_closed
      else
        false
      end
    end

    def user_today(user = User.current)
      user.respond_to?(:today) ? user.today : Date.current
    end

    def issue_editable?(issue, user = User.current)
      issue.respond_to?(:attributes_editable?) && issue.attributes_editable?(user)
    end

    def safe_attribute?(record, attribute, user = User.current)
      return false unless record.respond_to?(:safe_attribute?)

      begin
        record.safe_attribute?(attribute, user)
      rescue ArgumentError
        record.safe_attribute?(attribute)
      end
    end

    def issue_assignable_to?(issue, user = User.current)
      return false unless issue && user&.logged?
      return false unless issue.respond_to?(:assignable_users)

      issue.assignable_users.include?(user)
    end

    def allowed_issue_statuses(issue, user = User.current)
      return [] unless issue.respond_to?(:new_statuses_allowed_to)

      issue.new_statuses_allowed_to(user)
    rescue ArgumentError
      issue.new_statuses_allowed_to
    end

    def valid_watcher?(watchable, user)
      return false unless user.is_a?(User) && user.active?
      return watchable.valid_watcher?(user) if watchable.respond_to?(:valid_watcher?)
      return watchable.visible?(user) if watchable.respond_to?(:visible?)

      true
    end

    def add_watcher(watchable, user)
      if watchable.respond_to?(:add_watcher)
        watchable.add_watcher(user)
      elsif watchable.respond_to?(:set_watcher)
        watchable.set_watcher(user, true)
      end
    end
  end
end
