# frozen_string_literal: true

module UxToolkitIssueBadgesHelper
  STALE_ISSUE_DAYS_DEFAULT = 14
  STALE_ISSUE_DAYS_RANGE = 1..365

  def ux_toolkit_issue_overdue?(issue)
    return false unless issue&.due_date

    if issue.respond_to?(:overdue?)
      issue.overdue?
    else
      !RedmineUxToolkit::Compatibility.issue_closed?(issue) &&
        issue.due_date < RedmineUxToolkit::Compatibility.user_today
    end
  end

  def ux_toolkit_issue_overdue_days(issue)
    return 0 unless ux_toolkit_issue_overdue?(issue)

    (RedmineUxToolkit::Compatibility.user_today - issue.due_date).to_i
  end

  def ux_toolkit_issue_due_today?(issue)
    return false unless issue&.due_date

    !RedmineUxToolkit::Compatibility.issue_closed?(issue) &&
      issue.due_date == RedmineUxToolkit::Compatibility.user_today
  end

  def ux_toolkit_stale_issue_days_setting
    settings = Setting.plugin_redmine_ux_toolkit || {}
    days = settings.fetch('stale_issue_days', STALE_ISSUE_DAYS_DEFAULT).to_i

    STALE_ISSUE_DAYS_RANGE.cover?(days) ? days : STALE_ISSUE_DAYS_DEFAULT
  end

  def ux_toolkit_issue_stale?(issue)
    return false unless issue&.updated_on
    return false if RedmineUxToolkit::Compatibility.issue_closed?(issue)

    ux_toolkit_issue_stale_days(issue) >= ux_toolkit_stale_issue_days_setting
  end

  def ux_toolkit_issue_stale_days(issue)
    return 0 unless issue&.updated_on

    [RedmineUxToolkit::Compatibility.user_today - ux_toolkit_issue_updated_on_date(issue), 0].max.to_i
  end

  def ux_toolkit_issue_unassigned?(issue)
    return false unless issue

    !RedmineUxToolkit::Compatibility.issue_closed?(issue) && issue.assigned_to_id.blank?
  end

  def ux_toolkit_overdue_badge(issue)
    return ''.html_safe unless ux_toolkit_issue_overdue?(issue)

    days = ux_toolkit_issue_overdue_days(issue)
    text = days.positive? ? l(:label_ux_toolkit_overdue_by_days, count: days) : l(:label_ux_toolkit_overdue_badge)

    content_tag(:span, text, class: 'ux-toolkit-issue-badge ux-toolkit-overdue-badge')
  end

  def ux_toolkit_due_today_badge(issue)
    return ''.html_safe unless ux_toolkit_issue_due_today?(issue)

    content_tag(:span, l(:label_ux_toolkit_due_today_badge), class: 'ux-toolkit-issue-badge ux-toolkit-due-today-badge')
  end

  def ux_toolkit_stale_issue_badge(issue)
    return ''.html_safe unless ux_toolkit_issue_stale?(issue)

    content_tag(
      :span,
      l(:label_ux_toolkit_stale_issue_days, count: ux_toolkit_issue_stale_days(issue)),
      class: 'ux-toolkit-issue-badge ux-toolkit-stale-issue-badge'
    )
  end

  def ux_toolkit_unassigned_issue_badge(issue)
    return ''.html_safe unless ux_toolkit_issue_unassigned?(issue)

    content_tag(
      :span,
      l(:label_ux_toolkit_unassigned_issue_badge),
      class: 'ux-toolkit-issue-badge ux-toolkit-unassigned-issue-badge'
    )
  end

  def ux_toolkit_sla_light_active_badge(issue)
    return ''.html_safe unless RedmineUxToolkit::Services::SlaLight.active_for?(issue)

    content_tag(
      :span,
      l(:label_ux_toolkit_sla_light_active_badge),
      class: 'ux-toolkit-issue-badge ux-toolkit-sla-light-active-badge',
      title: l(:text_ux_toolkit_sla_light_active_badge_help)
    )
  end

  def ux_toolkit_issue_badges(issue)
    badges = []
    badges << ux_toolkit_overdue_badge(issue) if ux_toolkit_issue_overdue?(issue)
    badges << ux_toolkit_due_today_badge(issue) if badges.empty? && ux_toolkit_issue_due_today?(issue)
    badges << ux_toolkit_stale_issue_badge(issue) if ux_toolkit_issue_stale?(issue)
    badges << ux_toolkit_unassigned_issue_badge(issue) if ux_toolkit_issue_unassigned?(issue)
    badges << ux_toolkit_sla_light_active_badge(issue) if RedmineUxToolkit::Services::SlaLight.active_for?(issue)

    safe_join(badges.reject(&:blank?), ' ')
  end

  def ux_toolkit_issue_link_with_badges(issue)
    safe_join([link_to_issue(issue), ux_toolkit_issue_badges(issue)].reject(&:blank?), ' ')
  end

  private

  def ux_toolkit_issue_updated_on_date(issue)
    time_zone = User.current.respond_to?(:time_zone) ? User.current.time_zone : nil
    updated_on = issue.updated_on

    time_zone ? updated_on.in_time_zone(time_zone).to_date : updated_on.to_date
  end
end
