# frozen_string_literal: true

class UxToolkitMyWorkController < ApplicationController
  before_action :require_login

  ISSUE_BLOCK_LIMIT = 10

  helper :issues
  helper :queries
  helper :projects
  helper :ux_toolkit_issue_badges
  helper :ux_toolkit_my_work

  def index
    @preference = current_preference
    @visible_blocks = @preference.resolved_visible_dashboard_block_keys
    @block_totals = {}

    load_issue_blocks
    load_project_and_query_blocks
    load_recent_blocks
  end

  def settings
    @preference = current_preference
    @visible_blocks = @preference.resolved_visible_dashboard_block_keys
    @block_order = @preference.resolved_dashboard_block_order
  end

  def update_settings
    @preference = current_preference
    @preference.visible_dashboard_block_keys = params.dig(:ux_toolkit_my_work, :visible_blocks)
    @preference.dashboard_block_order = params.dig(:ux_toolkit_my_work, :block_order)

    if @preference.save
      flash[:notice] = l(:notice_ux_toolkit_dashboard_settings_saved)
      redirect_to ux_toolkit_my_work_path
    else
      @visible_blocks = @preference.visible_dashboard_block_keys
      @block_order = @preference.resolved_dashboard_block_order
      flash.now[:error] = l(:error_ux_toolkit_dashboard_settings_save_failed)
      render :settings
    end
  end

  private

  def current_preference
    UxToolkitUserPreference.find_or_initialize_by(user_id: User.current.id)
  end

  def block_visible?(block)
    @visible_blocks.include?(block)
  end

  def load_issue_blocks
    issues = assigned_issues

    if block_visible?(UxToolkitUserPreference::DASHBOARD_BLOCK_ASSIGNED_TO_ME)
      @block_totals[UxToolkitUserPreference::DASHBOARD_BLOCK_ASSIGNED_TO_ME] = issues.count
      @assigned_issues = issues.limit(ISSUE_BLOCK_LIMIT)
    end
    today = RedmineUxToolkit::Compatibility.user_today

    load_issue_block(UxToolkitUserPreference::DASHBOARD_BLOCK_DUE_TODAY, issues.where(due_date: today), :@due_today_issues)
    load_issue_block(UxToolkitUserPreference::DASHBOARD_BLOCK_OVERDUE, issues.where("#{Issue.table_name}.due_date < ?", today), :@overdue_issues)
    load_issue_block(
      UxToolkitUserPreference::DASHBOARD_BLOCK_DUE_SOON,
      issues.where(due_date: (today + 1)..(today + 7)),
      :@due_soon_issues
    )
  end

  def load_project_and_query_blocks
    if block_visible?(UxToolkitUserPreference::DASHBOARD_BLOCK_FAVORITE_PROJECTS)
      relation = UxToolkitFavoriteProject.visible_for(User.current)
      @block_totals[UxToolkitUserPreference::DASHBOARD_BLOCK_FAVORITE_PROJECTS] = relation.count
      @favorite_projects = relation.limit(10).map(&:project).compact
    end

    if block_visible?(UxToolkitUserPreference::DASHBOARD_BLOCK_FAVORITE_QUERIES)
      relation = UxToolkitFavoriteQuery.visible_for(User.current)
      @block_totals[UxToolkitUserPreference::DASHBOARD_BLOCK_FAVORITE_QUERIES] = relation.count
      @favorite_queries = relation.limit(10).map(&:query).compact
    end
  end

  def load_recent_blocks
    if block_visible?(UxToolkitUserPreference::DASHBOARD_BLOCK_RECENT_ISSUES)
      relation = UxToolkitRecentIssue.visible_for(User.current)
      @block_totals[UxToolkitUserPreference::DASHBOARD_BLOCK_RECENT_ISSUES] = relation.count
      @recent_issues = relation.limit(UxToolkitRecentIssue.configured_limit)
    end

    if block_visible?(UxToolkitUserPreference::DASHBOARD_BLOCK_RECENT_PROJECTS)
      relation = UxToolkitRecentProject.visible_for(User.current)
      @block_totals[UxToolkitUserPreference::DASHBOARD_BLOCK_RECENT_PROJECTS] = relation.count
      @recent_projects = relation.limit(UxToolkitRecentProject.configured_limit)
    end
  end

  def assigned_issues
    Issue.visible(User.current)
         .open
         .where(assigned_to_id: User.current.id)
         .includes(:project, :status, :priority)
         .joins(:priority)
         .order(
           "#{IssuePriority.table_name}.position DESC",
           "#{Issue.table_name}.due_date ASC",
           "#{Issue.table_name}.updated_on DESC"
         )
  end

  def load_issue_block(block, relation, variable)
    return unless block_visible?(block)

    @block_totals[block] = relation.count
    instance_variable_set(variable, relation.limit(ISSUE_BLOCK_LIMIT))
  end
end
