class Sparkpost::TransmissionService < ApplicationService
  def initialize(batch_email_id)
    @batch_email_id = batch_email_id
    @url = 'https://api.sparkpost.com/api/v1/transmissions'

    @header = {
      Accept: :json,
      'Context-Type' => :json,
      Authorization: Rails.application.secrets.sparkpost[:api_key]
    }
  end

  def call
    RestClient.post(@url, data, @header)
    batch_email.sent!
  rescue RestClient::Exception
    batch_email.failed!
  end

  private
    def batch_email
      @batch_email ||= Communication::BatchEmail.find(@batch_email_id)
    end

    def sending_domain
      @sending_domain ||= batch_email.school.communication_sparkpost_sending_config.domain
    end

    def bounce_domain
      @bounce_domain ||= batch_email.school.communication_sparkpost_bounce_config&.domain
    end

    def recipients
      batch_email.recipients.includes(associated: :primary_email_address)
    end

    def data
      {
        campaign_id: "schjob3:#{batch_email.id}",
        recipients: recipients.map { |r| recipient_props(r) },
        content: {
          from: {
            email: "info@#{sending_domain}"
          },
          subject: batch_email.subject,
          html: batch_email.html
        }
      }.to_json
    end

    def recipient_props(recipient)
      {}.tap do |props|
        props[:address] = {
          email: recipient.associated.primary_email_address.address,
          name: recipient.associated.full_name
        }
        props[:metadata] = {
          recipient_id: recipient.id
        }

        return props unless bounce_domain

        props[:return_path] = "bounce@#{bounce_domain}"
      end
    end
end
