# frozen_string_literal: true

require_relative 'redmine_ux_toolkit/compatibility'
require_dependency File.expand_path('../app/helpers/ux_toolkit_compatibility_helper', __dir__)
require_dependency File.expand_path('../app/helpers/ux_toolkit_issue_badges_helper', __dir__)
require_dependency File.expand_path('../app/helpers/ux_toolkit_issue_hints_helper', __dir__)
require_relative 'redmine_ux_toolkit/services/landing_page_resolver'
require_relative 'redmine_ux_toolkit/services/issue_assign_to_me'
require_relative 'redmine_ux_toolkit/services/issue_assign_to_me_and_start'
require_relative 'redmine_ux_toolkit/services/issue_quick_status_actions'
require_relative 'redmine_ux_toolkit/services/checklists'
require_relative 'redmine_ux_toolkit/services/issue_close_guards'
require_relative 'redmine_ux_toolkit/services/checklist_template_copier'
require_relative 'redmine_ux_toolkit/services/tracker_checklist_template_inserter'
require_relative 'redmine_ux_toolkit/services/issue_author_watcher'
require_relative 'redmine_ux_toolkit/services/issue_commenter_watcher'
require_relative 'redmine_ux_toolkit/services/issue_reminder_emails'
require_relative 'redmine_ux_toolkit/services/helpdesk_mail_fetch'
require_relative 'redmine_ux_toolkit/services/cron_monitor'
require_relative 'redmine_ux_toolkit/services/sla_light'
require_relative 'redmine_ux_toolkit/services/team_workload'
require_relative 'redmine_ux_toolkit/services/project_health'
require_relative 'redmine_ux_toolkit/services/repository_refresh'
require_relative 'redmine_ux_toolkit/services/attachment_storage'
require_relative 'redmine_ux_toolkit/services/attachment_preview'
require_relative 'redmine_ux_toolkit/services/modern_ui'
require_relative 'redmine_ux_toolkit/services/custom_css'
require_relative 'redmine_ux_toolkit/services/external_links_processor'
require_relative 'redmine_ux_toolkit/services/log_files'
require_relative 'redmine_ux_toolkit/services/navigation_links'
require_relative 'redmine_ux_toolkit/services/settings_overview'
require_relative 'redmine_ux_toolkit/services/operational_status'
require_relative 'redmine_ux_toolkit/services/recent_issue_tracker'
require_relative 'redmine_ux_toolkit/services/recent_project_tracker'
require_relative 'redmine_ux_toolkit/cron/noop_job'
require_relative 'redmine_ux_toolkit/cron/jobs/recurring_issues_job'
require_relative 'redmine_ux_toolkit/cron/jobs/issue_reminder_emails_job'
require_relative 'redmine_ux_toolkit/cron/jobs/helpdesk_mail_fetch_job'
require_relative 'redmine_ux_toolkit/cron/jobs/repository_refresh_job'
require_relative 'redmine_ux_toolkit/cron/jobs/attachment_trash_cleanup_job'
require_relative 'redmine_ux_toolkit/cron/runner'
require_relative 'redmine_ux_toolkit/hooks/my_account_hook'
require_relative 'redmine_ux_toolkit/patches/account_controller_patch'
require_relative 'redmine_ux_toolkit/patches/application_controller_patch'
require_relative 'redmine_ux_toolkit/patches/application_helper_patch'
require_relative 'redmine_ux_toolkit/patches/issues_controller_patch'
require_relative 'redmine_ux_toolkit/patches/issues_helper_patch'
require_relative 'redmine_ux_toolkit/patches/issue_checklist_close_guard_patch'
require_relative 'redmine_ux_toolkit/patches/menu_visibility_patch'
require_relative 'redmine_ux_toolkit/patches/my_controller_patch'
require_relative 'redmine_ux_toolkit/patches/projects_controller_patch'
require_relative 'redmine_ux_toolkit/patches/project_patch'
require_relative 'redmine_ux_toolkit/patches/projects_helper_patch'
require_relative 'redmine_ux_toolkit/patches/queries_helper_patch'
require_relative 'redmine_ux_toolkit/patches/settings_controller_patch'
require_relative 'redmine_ux_toolkit/patches/tracker_patch'

module RedmineUxToolkit
  def self.apply_patches!
    require_dependency 'account_controller'
    require_dependency 'application_controller'
    require_dependency 'application_helper'
    require_dependency 'issues_controller'
    require_dependency 'issues_helper'
    require_dependency 'issue'
    require_dependency 'my_controller'
    require_dependency 'projects_controller'
    require_dependency 'project'
    require_dependency 'projects_helper'
    require_dependency 'queries_helper'
    require_dependency 'settings_controller'
    require_dependency 'tracker'

    Hooks.register!

    IssuesController.helper :ux_toolkit_issue_badges if IssuesController.respond_to?(:helper)

    if defined?(ActionView::Base) &&
       !ActionView::Base.included_modules.include?(UxToolkitCompatibilityHelper)
      ActionView::Base.include UxToolkitCompatibilityHelper
    end

    if defined?(ApplicationHelper) &&
       !ApplicationHelper.included_modules.include?(UxToolkitCompatibilityHelper)
      ApplicationHelper.include UxToolkitCompatibilityHelper
    end

    [IssuesHelper, ProjectsHelper, QueriesHelper].each do |helper_module|
      unless helper_module.included_modules.include?(UxToolkitCompatibilityHelper)
        helper_module.include UxToolkitCompatibilityHelper
      end
    end

    unless IssuesHelper.included_modules.include?(UxToolkitIssueBadgesHelper)
      IssuesHelper.include UxToolkitIssueBadgesHelper
    end

    unless QueriesHelper.included_modules.include?(UxToolkitIssueBadgesHelper)
      QueriesHelper.include UxToolkitIssueBadgesHelper
    end

    unless IssuesHelper.included_modules.include?(UxToolkitIssueHintsHelper)
      IssuesHelper.include UxToolkitIssueHintsHelper
    end

    unless AccountController.ancestors.include?(Patches::AccountControllerPatch)
      AccountController.prepend Patches::AccountControllerPatch
    end

    unless ApplicationController.ancestors.include?(Patches::ApplicationControllerPatch)
      ApplicationController.prepend Patches::ApplicationControllerPatch
    end

    unless ApplicationHelper.ancestors.include?(Patches::ApplicationHelperPatch)
      ApplicationHelper.prepend Patches::ApplicationHelperPatch
    end

    unless Redmine::MenuManager::MenuHelper.ancestors.include?(Patches::MenuVisibilityPatch)
      Redmine::MenuManager::MenuHelper.prepend Patches::MenuVisibilityPatch
    end

    unless IssuesController.ancestors.include?(Patches::IssuesControllerPatch)
      IssuesController.prepend Patches::IssuesControllerPatch
    end

    unless IssuesHelper.ancestors.include?(Patches::IssuesHelperPatch)
      IssuesHelper.prepend Patches::IssuesHelperPatch
    end

    unless Issue.ancestors.include?(Patches::IssueChecklistCloseGuardPatch)
      Issue.prepend Patches::IssueChecklistCloseGuardPatch
    end

    unless MyController.ancestors.include?(Patches::MyControllerPatch)
      MyController.prepend Patches::MyControllerPatch
    end

    unless ProjectsController.ancestors.include?(Patches::ProjectsControllerPatch)
      ProjectsController.prepend Patches::ProjectsControllerPatch
    end

    unless Project.ancestors.include?(Patches::ProjectPatch)
      Project.prepend Patches::ProjectPatch
    end

    unless ProjectsHelper.ancestors.include?(Patches::ProjectsHelperPatch)
      # Preserve the current implementation because legacy plugins may alias-wrap
      # the prepended method later and otherwise create a recursive super chain.
      Patches::ProjectsHelperPatch.capture_original_project_settings_tabs(
        ProjectsHelper.instance_method(:project_settings_tabs)
      )
      ProjectsHelper.prepend Patches::ProjectsHelperPatch
    end

    unless QueriesHelper.ancestors.include?(Patches::QueriesHelperPatch)
      # Preserve the core implementation because legacy plugins may alias-wrap
      # the prepended method later and otherwise create a recursive super chain.
      Patches::QueriesHelperPatch.capture_original_column_content(
        QueriesHelper.instance_method(:column_content)
      )
      QueriesHelper.prepend Patches::QueriesHelperPatch
    end

    unless SettingsController.ancestors.include?(Patches::SettingsControllerPatch)
      SettingsController.prepend Patches::SettingsControllerPatch
    end

    unless Tracker.ancestors.include?(Patches::TrackerPatch)
      Tracker.prepend Patches::TrackerPatch
    end
  end
end

RedmineUxToolkit.apply_patches!
RedmineUxToolkit::Compatibility.to_prepare do
  RedmineUxToolkit.apply_patches!
end
