# frozen_string_literal: true

module VulnerabilityExternalIssueLinks
  class CreateService < BaseService
    def initialize(user, vulnerability, external_provider, link_type: Vulnerabilities::ExternalIssueLink.link_types[:created])
      @user = user
      @vulnerability = vulnerability
      @external_provider = external_provider
      @link_type = link_type
      @external_provider_service = prepare_external_provider_service
      @external_issue_link = prepare_external_issue_link
    end

    def execute
      return error(['External provider service is not configured to create issues.']) unless external_provider_service&.configured_to_create_issues_from_vulnerabilities?
      return error(external_issue_link.errors.full_messages) unless external_issue_link.valid?

      external_issue = create_external_issue

      if external_issue.has_errors?
        error(external_issue.errors.values)
      else
        if external_issue_link.update(external_issue_key: external_issue.id)
          success
        else
          error(external_issue_link.errors.full_messages)
        end
      end
    end

    private

    attr_reader :user, :vulnerability, :link_type, :external_provider, :external_provider_service, :external_issue_link
    delegate :project, to: :vulnerability

    def create_external_issue
      summary = _('Investigate vulnerability: %{title}') % { title: vulnerability.title }
      description = vulnerability.present.jira_issue_description

      external_provider_service.create_issue(summary, description, user)
    end

    def prepare_external_provider_service
      case external_provider
      when 'jira' then project&.jira_service
      end
    end

    def prepare_external_issue_link
      Vulnerabilities::ExternalIssueLink.new(
        author: user,
        vulnerability: vulnerability,
        link_type: link_type,
        external_type: external_provider,
        external_project_key: external_provider_service&.project_key,
        external_issue_key: 0
      )
    end

    def success
      ServiceResponse.success(payload: { record: external_issue_link })
    end

    def error(message)
      ServiceResponse.error(message: message)
    end

    def result_payload
      { record: issue_link }
    end
  end
end
