# frozen_string_literal: true

module RedmineUxToolkit
  module Services
    class SettingsOverview
      Item = Struct.new(:key, :label_key, :tab, :status, :keywords, keyword_init: true)

      class << self
        def items(settings = plugin_settings)
          [
            item(:landing_pages, :label_ux_toolkit_global_landing_page_after_login, :landing_pages_and_links, configured?(settings, 'global_landing_page_type')),
            item(:navigation, :label_ux_toolkit_navigation, :landing_pages_and_links, true),
            item(:my_work, :label_ux_toolkit_my_work, :landing_pages_and_links, true),
            item(:notices, :label_ux_toolkit_tab_notices, :notices, notice_configured?(settings)),
            item(:recent_items, :label_ux_toolkit_tab_recent_items, :recent_items, true),
            item(:issue_actions, :label_ux_toolkit_issue_quick_actions, :issues, issue_actions_status(settings)),
            item(:issue_badges, :label_ux_toolkit_issue_badges, :issues, true),
            item(:close_guards, :label_ux_toolkit_issue_close_guards, :issues, any_enabled?(settings, 'prevent_closing_with_open_checklist_items', 'prevent_closing_with_open_subtasks')),
            item(:checklists, :label_ux_toolkit_checklists, :issues, enabled?(settings, 'enable_checklists', default: true)),
            item(:watchers, :label_ux_toolkit_watchers, :issues, any_enabled?(settings, 'auto_watch_issue_author', 'auto_watch_issue_commenters')),
            item(:issue_quality, :label_ux_toolkit_issue_quality, :issues, enabled?(settings, 'enable_issue_quality_check')),
            item(:sla_light, :label_ux_toolkit_sla_light, :sla_light, enabled?(settings, 'enable_sla_light')),
            item(:recurring, :label_ux_toolkit_recurring_issue_rules, :scheduled_tasks, recurring_status),
            item(:reminders, :label_ux_toolkit_issue_reminder_emails, :scheduled_tasks, reminder_status(settings)),
            item(:repository_refresh, :label_ux_toolkit_repository_refresh, :scheduled_tasks, enabled?(settings, 'enable_repository_refresh_scheduler', default: true)),
            item(:cron_monitoring, :label_ux_toolkit_cron_monitoring, :scheduled_tasks, cron_monitoring_status(settings)),
            item(:attachment_storage, :label_ux_toolkit_attachment_storage, :attachments, enabled?(settings, 'enable_attachment_trash')),
            item(:attachment_preview, :label_ux_toolkit_attachment_preview, :attachments, enabled?(settings, 'attachment_preview_enabled', default: true)),
            item(:ticket_templates, :label_ux_toolkit_ticket_templates, :ticket_templates_and_text_snippets, available_status),
            item(:text_snippets, :label_ux_toolkit_text_snippets, :ticket_templates_and_text_snippets, available_status),
            item(:modern_ui, :label_ux_toolkit_modern_ui, :landing_pages_and_links, enabled?(settings, 'modern_ui_enabled')),
            item(:custom_code, :label_ux_toolkit_tab_custom_css_js, :custom_css, custom_code_status)
          ]
        end

        private

        def item(key, label_key, tab, status)
          normalized_status = case status
                              when true then :enabled
                              when false then :disabled
                              else status
                              end

          Item.new(key: key, label_key: label_key, tab: tab.to_s, status: normalized_status, keywords: key.to_s.tr('_', ' '))
        end

        def plugin_settings
          Setting.plugin_redmine_ux_toolkit || {}
        end

        def configured?(settings, key)
          settings[key].present? ? :enabled : :available
        end

        def enabled?(settings, key, default: false)
          settings.fetch(key, default ? '1' : '0').to_s == '1' ? :enabled : :disabled
        end

        def any_enabled?(settings, *keys)
          keys.any? { |key| enabled?(settings, key) == :enabled } ? :enabled : :disabled
        end

        def notice_configured?(settings)
          settings.values_at('login_notice_text', 'global_new_issue_notice_text').any?(&:present?) ? :enabled : :available
        end

        def issue_actions_status(settings)
          return :needs_configuration if enabled?(settings, 'enable_assign_to_me_and_start_button') == :enabled && settings['assign_to_me_and_start_status_id'].blank?
          return :needs_configuration if enabled?(settings, 'enable_quick_status_actions') == :enabled && Array(settings['quick_status_action_status_ids']).reject(&:blank?).empty?

          any_enabled?(settings, 'enable_assign_to_me_button', 'enable_assign_to_me_and_start_button', 'enable_quick_status_actions')
        end

        def reminder_status(settings)
          return :disabled unless enabled?(settings, 'enable_issue_reminder_emails') == :enabled
          return :needs_configuration if IssueReminderEmails.weekday_keys(settings).empty?

          :enabled
        end

        def cron_monitoring_status(settings)
          return :disabled unless CronMonitor.enabled?(settings)

          recipient = CronMonitor.monitoring_recipient(
            settings,
            server_admin_email: CronMonitor.server_admin_email
          )
          recipient.present? ? :enabled : :needs_configuration
        end

        def recurring_status
          return :unavailable unless table_exists?('ux_toolkit_recurring_issue_rules')

          UxToolkitRecurringIssueRule.enabled.exists? ? :enabled : :available
        rescue ActiveRecord::ActiveRecordError
          :unavailable
        end

        def custom_code_status
          CustomCss.sanitized_css.present? || CustomCss.javascript.present? ? :enabled : :available
        end

        def available_status
          :available
        end

        def table_exists?(name)
          ActiveRecord::Base.connection.data_source_exists?(name)
        rescue ActiveRecord::ActiveRecordError
          false
        end
      end
    end
  end
end
