class SignupService

  attr_reader :provider, :plans, :session, :account_params, :user_params

  def initialize(provider:, plans:, session:, account_params:, user_params:)
    @provider       = provider
    @plans          = plans
    @session        = session
    @account_params = account_params
    @user_params    = user_params
  end

  def create
    signup_user = nil

    signup = provider.signup_with_plans(plans) do |buyer, user|
      buyer.provider_account       = provider
      buyer.unflattened_attributes = account_params
      user.attributes  = user_params
      user.signup_type = :new_signup
      user.account     = buyer
      signup_user      = user

      strategy.on_new_user(user, session)

      yield(buyer, user) if block_given?
    end

    if signup
      push_webhooks(signup_user)
      track_signup
      clear_session
    end

    signup_user
  end

  private

  def push_webhooks(user)
    webhook_name  = 'created'.freeze
    buyer_account = user.account

    buyer_account.web_hook_event!(event: webhook_name)
    user.web_hook_event!(event: webhook_name)

    buyer_account.bought_cinstances.each do |cinstance|
      cinstance.web_hook_event!(event: webhook_name)
    end
  end

  def clear_session
    strategy.on_signup_complete(session)
  end

  def track_signup
    ThreeScale::Analytics.track(provider.first_admin,
                                'Acquired new Developer Account'.freeze,
                                strategy.track_signup_options(session: session))
  end

  def strategy
    @strategy ||= Authentication::Strategy.build(provider)
  end
end
