module EasyPatch
  module AdminControllerPatch

    def self.included(base)
      base.send(:include, InstanceMethods)
      base.class_eval do

        helper :projects, :easy_query
        include ProjectsHelper

        alias_method_chain :require_admin, :easy_extensions
        alias_method_chain :projects, :easy_extensions
        alias_method_chain :plugins, :easy_extensions

        def manage_plugins
          redirect_to admin_plugins_path
        end

        private

        def find_root
          @root = Project.find(params[:root_id]) if params[:root_id]
        rescue ActiveRecord::RecordNotFound
        end

        def find_projects_for_root(root_id=nil)
          t = Project.arel_table
          if @status.present?
            @query.entity_scope = Project.where( "EXISTS ( SELECT 1 FROM projects as children WHERE children.lft >= projects.lft AND children.rgt <= projects.rgt AND children.status = #{@status}#{(' AND ' + @name_statement) if @name_statement})" )
          end
          @query.add_additional_statement t[:parent_id].eq(root_id).to_sql
          @projects = prepare_easy_query_render(@query, :limit => (root_id ? nil : per_page_option))
          @with_visible_childs = Project.where( "EXISTS ( SELECT 1 FROM projects as children WHERE children.lft > projects.lft AND children.rgt < projects.rgt#{(' AND children.status = ' + @status ) if @status.present?}#{(' AND ' + @name_statement) if @name_statement})").where(parent_id: root_id).pluck(:id)
        end

      end
    end

    module InstanceMethods

      def plugins_with_easy_extensions
        @plugins = Redmine::Plugin.all(:only_visible => true).sort_by { |p| p.name.is_a?(Symbol) ? l(p.name) : p.name }
      end

      def projects_with_easy_extensions
        @query = EasyProjectQuery.new(:name => l(:label_project_plural))
        @query.entity_scope = Project
        @query.filters = {}
        if params[:name]
          pattern = {:p => "%#{params[:name].to_s.strip.downcase}%"}
          @name_statement = Project.send(:sanitize_sql_for_conditions, ['(LOWER(children.identifier) LIKE :p OR LOWER(children.name) LIKE :p)', pattern])
        end

        @status = params[:status] || Project::STATUS_ACTIVE.to_s
        @query.user = User.current

        @collapse = !request.xhr?

        sort_init(@query.sort_criteria_init)

        sort_update({'lft' => "#{Project.table_name}.lft"}.merge(@query.sortable_columns))

        if !params[:root_id]
          set_pagination
          find_projects_for_root(nil)
        else
          return render_404 unless find_root
          find_projects_for_root(@root.id)
        end

        if request.xhr?
          if params[:root_id]
            render :template => 'admin/projects', layout: false, locals: {projects: @projects}
          else
            render :action => 'projects', layout: false
          end
        end
      end

      def require_admin_with_easy_extensions
        require_admin_or_lesser_admin
      end

    end

  end

end
EasyExtensions::PatchManager.register_controller_patch 'AdminController', 'EasyPatch::AdminControllerPatch'
