class NewAccountsQuery
  attr_reader :account

  def initialize(account)
    @account = account
  end

  def within_timeframe(range:, granularity: :day)
    result_date_format = granularity_to_date_format(granularity)
    timezone_offset    = Time.zone.formatted_offset
    timezone_name      = Time.zone.tzinfo.name

    groups = account.buyer_accounts
      .where.has do
        date(
          coalesce(
            convert_tz(created_at, quoted('UTC'),    quoted(timezone_name)),
            convert_tz(created_at, quoted('+00:00'), quoted(timezone_offset))
          )
        )
        .in(range)
      end
      .group( # https://github.com/rails/arel/issues/383 - so can't be Arel
        "DATE_FORMAT(
          COALESCE(
            CONVERT_TZ(created_at, 'UTC',    '#{timezone_name}'),
            CONVERT_TZ(created_at, '+00:00', '#{timezone_offset}')
          ),
          '#{result_date_format}'
        )"
      )
      .count(:id)

    range.map do |range_date|

      range_date_in_format = range_date.strftime(result_date_format)

      [range_date_in_format, groups.fetch(range_date_in_format, 0)]
    end.to_h
  end

  private

  def granularity_to_date_format(granularity)
    case granularity
    when :year
      '%Y'
    when :month
      '%Y-%m'
    when :day
      '%Y-%m-%d'
    when :hour
      '%Y-%m-%dT%H'
    else
      fail "Unknown granularity #{granularity.inspect}"
    end
  end
end
