# frozen_string_literal: true

module RedmineUxToolkit
  module Patches
    module QueriesHelperPatch
      class << self
        attr_reader :original_column_content

        def capture_original_column_content(method)
          @original_column_content = method
        end
      end

      # Redmine does not expose a hook inside saved query sidebar links.
      def query_links(title, queries)
        return '' if queries.empty?

        url_params =
          if controller_name == 'issues'
            {controller: 'issues', action: 'index', project_id: @project}
          else
            {}
          end
        default_query_by_class = {}

        content_tag('h3', title) + "\n" +
          content_tag(
            'ul',
            queries.collect do |query|
              css = +'query'
              clear_link = +''
              clear_link_param = {set_filter: 1, sort: '', project_id: @project}

              default_query =
                default_query_by_class[query.class] ||= query.class.default(project: @project)
              if query == default_query
                css << ' default'
                clear_link_param[:without_default] = 1
              end

              if query == @query
                css << ' selected'
                clear_link += link_to_clear_query(clear_link_param)
              end

              content_tag(
                'li',
                link_to(
                  ux_toolkit_sidebar_query_label(query),
                  url_params.merge(query_id: query),
                  class: css,
                  title: ux_toolkit_query_description(query),
                  data: {disable_with: CGI.escapeHTML(query.name)}
                ) + clear_link.html_safe
              )
            end.join("\n").html_safe,
            class: 'queries'
          ) + "\n"
      end

      def column_content(column, item)
        if @ux_toolkit_resolving_column_content
          original_method = QueriesHelperPatch.original_column_content
          return original_method.bind(self).call(column, item) if original_method
        end

        @ux_toolkit_resolving_column_content = true
        begin
          content = super
          return ux_toolkit_issue_subject_with_badges(content, item) if ux_toolkit_issue_subject_column?(column, item)

          return content unless ux_toolkit_project_name_column?(column, item)
          return content unless ux_toolkit_favorite_project_ids.include?(item.id)

          safe_join([content, ux_toolkit_favorite_project_icon], ' ')
        ensure
          remove_instance_variable(:@ux_toolkit_resolving_column_content)
        end
      end

      private

      def ux_toolkit_sidebar_query_label(query)
        return query.name unless ux_toolkit_favorite_issue_query?(query)

        safe_join([query.name, ux_toolkit_favorite_query_icon], ' ')
      end

      def ux_toolkit_query_description(query)
        return unless query.respond_to?(:description)

        query.description
      end

      def ux_toolkit_favorite_issue_query?(query)
        query.is_a?(IssueQuery) &&
          User.current.logged? &&
          ux_toolkit_favorite_query_ids.include?(query.id)
      end

      def ux_toolkit_favorite_query_ids
        @ux_toolkit_favorite_query_ids ||=
          UxToolkitFavoriteQuery.where(user_id: User.current.id).pluck(:query_id)
      end

      def ux_toolkit_favorite_query_icon
        tag.span(
          ux_toolkit_sprite_icon('fav', l(:label_ux_toolkit_favorite_query), icon_only: true),
          class: 'icon-only icon-fav ux-toolkit-favorite-query-icon',
          title: l(:label_ux_toolkit_favorite_query)
        )
      end

      def ux_toolkit_project_name_column?(column, item)
        item.is_a?(Project) && column.name == :name && User.current.logged?
      end

      def ux_toolkit_issue_subject_column?(column, item)
        item.is_a?(Issue) && column.name == :subject && respond_to?(:ux_toolkit_sla_light_active_badge)
      end

      def ux_toolkit_issue_subject_with_badges(content, issue)
        badge = ux_toolkit_sla_light_active_badge(issue)
        return content if badge.blank?

        safe_join([content, badge], ' ')
      end

      def ux_toolkit_favorite_project_ids
        @ux_toolkit_favorite_project_ids ||=
          UxToolkitFavoriteProject.where(user_id: User.current.id).pluck(:project_id)
      end

      def ux_toolkit_favorite_project_icon
        tag.span(
          ux_toolkit_sprite_icon('fav', l(:label_ux_toolkit_favorite_project), icon_only: true),
          class: 'icon-only icon-fav ux-toolkit-favorite-project-icon',
          title: l(:label_ux_toolkit_favorite_project)
        )
      end
    end
  end
end
