# frozen_string_literal: true

class UxToolkitIssueActionsController < ApplicationController
  before_action :require_login
  before_action :find_visible_issue

  def assign_to_me
    unless RedmineUxToolkit::Services::IssueAssignToMe.enabled?
      flash[:error] = l(:error_ux_toolkit_issue_assign_to_me_not_allowed)
      return redirect_to issue_path(@issue)
    end

    if @issue.assigned_to_id == User.current.id
      flash[:notice] = l(:notice_ux_toolkit_issue_already_assigned_to_me)
      return redirect_to issue_path(@issue)
    end

    unless RedmineUxToolkit::Services::IssueAssignToMe.available?(@issue, User.current)
      flash[:error] = l(:error_ux_toolkit_issue_assign_to_me_not_allowed)
      return redirect_to issue_path(@issue)
    end

    @issue.init_journal(User.current)
    @issue.safe_attributes = {'assigned_to_id' => User.current.id.to_s}

    if @issue.save
      flash[:notice] = l(:notice_ux_toolkit_issue_assigned_to_me)
    else
      flash[:error] = l(:error_ux_toolkit_issue_assign_to_me_failed)
    end

    redirect_to issue_path(@issue)
  end

  def assign_to_me_and_start
    service = RedmineUxToolkit::Services::IssueAssignToMeAndStart

    unless service.enabled?
      flash[:error] = l(:error_ux_toolkit_issue_assign_to_me_not_allowed)
      return redirect_to issue_path(@issue)
    end

    target_status = service.target_status
    unless target_status
      flash[:error] = l(:error_ux_toolkit_assign_to_me_and_start_status_missing)
      return redirect_to issue_path(@issue)
    end

    if service.assigned_and_started?(@issue, User.current, target_status)
      flash[:notice] = l(:notice_ux_toolkit_issue_already_assigned_to_me_and_started)
      return redirect_to issue_path(@issue)
    end

    unless RedmineUxToolkit::Services::IssueAssignToMe.assignable_to_user?(@issue, User.current)
      flash[:error] = l(:error_ux_toolkit_issue_assign_to_me_not_allowed)
      return redirect_to issue_path(@issue)
    end

    unless service.status_allowed?(@issue, User.current, target_status)
      flash[:error] = l(:error_ux_toolkit_assign_to_me_and_start_status_not_allowed)
      return redirect_to issue_path(@issue)
    end

    @issue.init_journal(User.current)
    @issue.safe_attributes = {
      'assigned_to_id' => User.current.id.to_s,
      'status_id' => target_status.id.to_s
    }

    if @issue.save
      flash[:notice] = l(:notice_ux_toolkit_issue_assigned_to_me_and_started)
    else
      flash[:error] = @issue.errors.full_messages.to_sentence.presence ||
                      l(:error_ux_toolkit_issue_assign_to_me_and_start_failed)
    end

    redirect_to issue_path(@issue)
  end

  def change_status
    service = RedmineUxToolkit::Services::IssueQuickStatusActions

    unless service.enabled?
      flash[:error] = l(:error_ux_toolkit_status_change_not_allowed)
      return redirect_to issue_path(@issue)
    end

    unless RedmineUxToolkit::Compatibility.issue_editable?(@issue, User.current) &&
        RedmineUxToolkit::Compatibility.safe_attribute?(@issue, 'status_id', User.current)
      flash[:error] = l(:error_ux_toolkit_status_change_not_allowed)
      return redirect_to issue_path(@issue)
    end

    status = service.status_by_id(params[:status_id])
    unless status
      flash[:error] = l(:error_ux_toolkit_status_not_available)
      return redirect_to issue_path(@issue)
    end

    unless service.configured?(status)
      flash[:error] = l(:error_ux_toolkit_status_not_configured_as_quick_action)
      return redirect_to issue_path(@issue)
    end

    if @issue.status_id == status.id
      flash[:error] = l(:error_ux_toolkit_status_not_available)
      return redirect_to issue_path(@issue)
    end

    unless service.status_allowed?(@issue, User.current, status)
      flash[:error] = l(:error_ux_toolkit_status_not_allowed_by_workflow)
      return redirect_to issue_path(@issue)
    end

    @issue.init_journal(User.current)
    @issue.safe_attributes = {'status_id' => status.id.to_s}

    if @issue.save
      flash[:notice] = l(:notice_ux_toolkit_issue_status_changed, status: status.name)
    else
      flash[:error] = @issue.errors.full_messages.to_sentence.presence ||
                      l(:error_ux_toolkit_issue_status_change_failed)
    end

    redirect_to issue_path(@issue)
  end

  private

  def find_visible_issue
    @issue = Issue.visible(User.current).find(params[:id])
    @project = @issue.project
  rescue ActiveRecord::RecordNotFound
    render_404
  end
end
